All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sedat Dilek <sedat.dilek@googlemail.com>
To: "Yan, Zheng" <yanzheng@21cn.com>
Cc: Jiri Slaby <jirislaby@gmail.com>,
	Valdis.Kletnieks@vt.edu, Tim Chen <tim.c.chen@linux.intel.com>,
	"David S. Miller" <davem@davemloft.net>,
	ML netdev <netdev@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Stephen Rothwell <sfr@canb.auug.org.au>
Subject: Re: [next] unix stream crashes
Date: Sat, 3 Sep 2011 15:47:32 +0200	[thread overview]
Message-ID: <CA+icZUXULisfr6_EOrj8+q36UMo2mudcoJu3z0SX4T3x_OZQSg@mail.gmail.com> (raw)
In-Reply-To: <CAAM7YAkB3VVNMmBMVuvEZuV6oGZeyog37_sjFGUunu+15apvZA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4744 bytes --]

On Sat, Sep 3, 2011 at 2:30 PM, Yan, Zheng <yanzheng@21cn.com> wrote:
> The skb can be destructed before the while loop in unix_stream_sendmsg stops.
> please try below patch.
>
> ---
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index e6d9d10..f6d7ed7 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1577,6 +1577,7 @@ static int unix_stream_sendmsg(struct kiocb
> *kiocb, struct socket *sock,
>        int sent = 0;
>        struct scm_cookie tmp_scm;
>        bool fds_sent = false;
> +       bool scm_ref = true;
>        int max_level;
>
>        if (NULL == siocb->scm)
> @@ -1637,12 +1638,19 @@ static int unix_stream_sendmsg(struct kiocb
> *kiocb, struct socket *sock,
>                 */
>                size = min_t(int, size, skb_tailroom(skb));
>
> +               /*
> +                * pass the scm reference to the skb if a single skb is large
> +                * enough to hold all data.
> +                */
> +               if (!fds_sent && sent + size >= len)
> +                       scm_ref = false;
>
> -               /* Only send the fds and no ref to pid in the first buffer */
> -               err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent);
> +               /* Only send the fds in the first buffer */
> +               err = unix_scm_to_skb(siocb->scm, skb, !fds_sent,
> +                                       fds_sent || scm_ref);
>                if (err < 0) {
>                        kfree_skb(skb);
> -                       goto out;
> +                       goto out_err;
>                }
>                max_level = err + 1;
>                fds_sent = true;
> @@ -1650,7 +1658,7 @@ static int unix_stream_sendmsg(struct kiocb
> *kiocb, struct socket *sock,
>                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
>                if (err) {
>                        kfree_skb(skb);
> -                       goto out;
> +                       goto out_err;
>                }
>
>                unix_state_lock(other);
> @@ -1667,10 +1675,10 @@ static int unix_stream_sendmsg(struct kiocb
> *kiocb, struct socket *sock,
>                sent += size;
>        }
>
> -       if (skb)
> -               scm_release(siocb->scm);
> -       else
> +       if (scm_ref)
>                scm_destroy(siocb->scm);
> +       else
> +               scm_release(siocb->scm);
>        siocb->scm = NULL;
>
>        return sent;
> @@ -1683,9 +1691,10 @@ pipe_err:
>                send_sig(SIGPIPE, current, 0);
>        err = -EPIPE;
>  out_err:
> -       if (skb == NULL)
> +       if (scm_ref)
>                scm_destroy(siocb->scm);
> -out:
> +       else
> +               scm_release(siocb->scm);
>        siocb->scm = NULL;
>        return sent ? : err;
>  }
>
>

I have tested your patch on i386 against:

1. linux-next/patch-v3.1-rc3-next-20110826
2. scm-fix/0001-Revert-Scm-Remove-unnecessary-pid-credential-referen.patch
3. scm-fix-2/scm_send.patch
4. scm-fix-3/0001-Fix-unix-stream-crashes.patch

So the BROKEN scm-send path seems to be fixed, now!

As the patch arrived "malformed" in my mbox I git-am-ed it on top of
linux-next (next-20110826) GIT repository (patch attached).

After confirmation of Valdis (x86_64) and ACK-by Tim, I would
appreciate a proper patch with all Reported-by/Tested-by/S-o-b etc.
In my case I bisected the issue, I recall that there is sth. like
Bisected-by, so feel free to do so.

Doing now a 2nd run with:

1. linux-next/patch-v3.1-rc3-next-20110826
2. scm-fix-3/0001-Fix-unix-stream-crashes.patch

- Sedat -

> On Sat, Sep 3, 2011 at 2:23 PM, Jiri Slaby <jirislaby@gmail.com> wrote:
>> On 09/03/2011 07:54 AM, Sedat Dilek wrote:
>>>
>>> I saw similiar call-traces with put_cred_rcu() - besides with
>>> kmem_cache_alloc_trace().
>>> My post-it says:
>>> Kernel panic - not syncing: CRED: put_cred_rcu sees f67ac0c0 with usage
>>> -43
>>
>> Hm, Tim, it looks like you put a pid which you did not get?
>>
>> regards,
>> --
>> js
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>>
>

[-- Attachment #2: 0001-Fix-unix-stream-crashes.patch --]
[-- Type: text/x-diff, Size: 2267 bytes --]

From 54d8a5c590c06f070d9adbfffba0b32246d727e2 Mon Sep 17 00:00:00 2001
From: "Yan, Zheng" <yanzheng@21cn.com>
Date: Sat, 3 Sep 2011 14:30:19 +0200
Subject: [PATCH] Fix unix stream crashes

The skb can be destructed before the while loop in unix_stream_sendmsg stops.
please try below patch.
---
 net/unix/af_unix.c |   27 ++++++++++++++++++---------
 1 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e6d9d10..f6d7ed7 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1577,6 +1577,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 	int sent = 0;
 	struct scm_cookie tmp_scm;
 	bool fds_sent = false;
+	bool scm_ref = true;
 	int max_level;
 
 	if (NULL == siocb->scm)
@@ -1637,12 +1638,19 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		 */
 		size = min_t(int, size, skb_tailroom(skb));
 
+		/*
+		 * pass the scm reference to the skb if a single skb is large
+		 * enough to hold all data.
+		 */
+		if (!fds_sent && sent + size >= len)
+			scm_ref = false;
 
-		/* Only send the fds and no ref to pid in the first buffer */
-		err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent);
+		/* Only send the fds in the first buffer */
+		err = unix_scm_to_skb(siocb->scm, skb, !fds_sent,
+					fds_sent || scm_ref);
 		if (err < 0) {
 			kfree_skb(skb);
-			goto out;
+			goto out_err;
 		}
 		max_level = err + 1;
 		fds_sent = true;
@@ -1650,7 +1658,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
 		if (err) {
 			kfree_skb(skb);
-			goto out;
+			goto out_err;
 		}
 
 		unix_state_lock(other);
@@ -1667,10 +1675,10 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		sent += size;
 	}
 
-	if (skb)
-		scm_release(siocb->scm);
-	else
+	if (scm_ref)
 		scm_destroy(siocb->scm);
+	else
+		scm_release(siocb->scm);
 	siocb->scm = NULL;
 
 	return sent;
@@ -1683,9 +1691,10 @@ pipe_err:
 		send_sig(SIGPIPE, current, 0);
 	err = -EPIPE;
 out_err:
-	if (skb == NULL)
+	if (scm_ref)
 		scm_destroy(siocb->scm);
-out:
+	else
+		scm_release(siocb->scm);
 	siocb->scm = NULL;
 	return sent ? : err;
 }
-- 
1.7.6


  reply	other threads:[~2011-09-03 13:47 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-01 20:46 [next] unix stream crashes Jiri Slaby
2011-09-02  0:49 ` Valdis.Kletnieks
2011-09-02  1:40   ` Tim Chen
2011-09-02 16:12     ` Valdis.Kletnieks
2011-09-02 23:55       ` Tim Chen
2011-09-03  4:32         ` Sedat Dilek
2011-09-03  5:35         ` Valdis.Kletnieks
2011-09-03  5:54           ` Sedat Dilek
2011-09-03  6:23             ` Jiri Slaby
2011-09-03 12:30               ` Yan, Zheng 
2011-09-03 13:47                 ` Sedat Dilek [this message]
2011-09-03 14:46                   ` Sedat Dilek
2011-09-03 15:38                     ` Yan, Zheng 
2011-09-04 14:43                 ` Valdis.Kletnieks

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+icZUXULisfr6_EOrj8+q36UMo2mudcoJu3z0SX4T3x_OZQSg@mail.gmail.com \
    --to=sedat.dilek@googlemail.com \
    --cc=Valdis.Kletnieks@vt.edu \
    --cc=davem@davemloft.net \
    --cc=jirislaby@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=sedat.dilek@gmail.com \
    --cc=sfr@canb.auug.org.au \
    --cc=tim.c.chen@linux.intel.com \
    --cc=yanzheng@21cn.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.