lkml.org 
[lkml]   [2011]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectRe: [next] unix stream crashes
From
On Sat, Sep 3, 2011 at 1:55 AM, Tim Chen <tim.c.chen@linux.intel.com> wrote:
> On Fri, 2011-09-02 at 12:12 -0400, Valdis.Kletnieks@vt.edu wrote:
>> On Thu, 01 Sep 2011 18:40:45 PDT, Tim Chen said:
>>
>> > Yes, Jiri's log does indicate that something went wrong when releasing
>> > the skb, most likely due to changes in the pid and credentials ref
>> > count.  Unfortunately, I cannot duplicate the problem on my system.  Any
>> > info on your system to help me debug will be appreciated.  I'll try to
>> > take another look at the patch tomorrow.
>>
>> Dell Latitude E6500, Core2 T8700 processor, x86_64 kernel, a slightly mangled
>> Fedora Rawhide userspace.  I'd not be surprised if there's an idiocyncratic
>> setting in my .config that makes the bug crawl out of the woodwork on my box,
>> so I'm attaching the .config in case it provides some enlightenment.
>>
>> If you want me to try a debugging or test patch, let me know...
>
> Valdis,
>
> I've tried your config on a few different machines but I'm still not
> able to reproduce the problem.  Can you help me narrow things down?
> Please revert my original patch.  I've separated my original changes
> into two parts.  Try apply only the recv_scm.patch attached and try to
> boot.  Then apply only the send_scm.patch without the rcv_scm.patch and
> repeat.  Let me know which patch causes the boot problem.
>
> I'll like to isolate the problem to either the send path or receive
> path. My suspicion is the error handling portion of the send path is not
> quite right but I haven't yet found any issues after reviewing the
> patch.
>
> Thanks.
>
> Tim
>

Hi,

base for my testing was linux-next (next-20110826) which contains
first time the culprit commit.
I have tested on an i386 Debian/sid system, my kernel-config is attached.

BAD #1: next-20110826

GOOD #1: next-20110826 + Revert-patch

GOOD #2: next-20110826 + Revert-patch + scm_recv.patch

BAD #2: next-20110826 + Revert-patch + scm_send.patch

With BAD #2 I have seen a NULL derefence (*pde = 00000000) arosing
from kmem_cache_alloc_trace().
( Sorry, no digicam here for a screenshot. )

Hope this helps you.

Feel free to send me further patches and/or add a
Reported-by/Tested-by/Bisected-by if you like.

- Sedat -
From 827255d53008e66628acc83e6c7692cbe2dc1ba0 Mon Sep 17 00:00:00 2001
From: Sedat Dilek <sedat.dilek@gmail.com>
Date: Fri, 2 Sep 2011 23:55:46 +0200
Subject: [PATCH] Revert "Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path"

This reverts commit 0856a304091b33a8e8f9f9c98e776f425af2b625.
---
include/net/scm.h | 22 +++-------------------
net/unix/af_unix.c | 45 ++++++++++++++++-----------------------------
2 files changed, 19 insertions(+), 48 deletions(-)

diff --git a/include/net/scm.h b/include/net/scm.h
index 68e1e48..745460f 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -53,14 +53,6 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
cred_to_ucred(pid, cred, &scm->creds);
}

-static __inline__ void scm_set_cred_noref(struct scm_cookie *scm,
- struct pid *pid, const struct cred *cred)
-{
- scm->pid = pid;
- scm->cred = cred;
- cred_to_ucred(pid, cred, &scm->creds);
-}
-
static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
{
put_pid(scm->pid);
@@ -78,15 +70,6 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
__scm_destroy(scm);
}

-static __inline__ void scm_release(struct scm_cookie *scm)
-{
- /* keep ref on pid and cred */
- scm->pid = NULL;
- scm->cred = NULL;
- if (scm->fp)
- __scm_destroy(scm);
-}
-
static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
struct scm_cookie *scm)
{
@@ -125,14 +108,15 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
if (!msg->msg_control) {
if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
msg->msg_flags |= MSG_CTRUNC;
- if (scm && scm->fp)
- __scm_destroy(scm);
+ scm_destroy(scm);
return;
}

if (test_bit(SOCK_PASSCRED, &sock->flags))
put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);

+ scm_destroy_cred(scm);
+
scm_passec(sock, msg, scm);

if (!scm->fp)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e6d9d10..ec68e1c 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1378,17 +1378,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
return max_level;
}

-static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb,
- bool send_fds, bool ref)
+static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
{
int err = 0;
- if (ref) {
- UNIXCB(skb).pid = get_pid(scm->pid);
- UNIXCB(skb).cred = get_cred(scm->cred);
- } else {
- UNIXCB(skb).pid = scm->pid;
- UNIXCB(skb).cred = scm->cred;
- }
+ UNIXCB(skb).pid = get_pid(scm->pid);
+ UNIXCB(skb).cred = get_cred(scm->cred);
UNIXCB(skb).fp = NULL;
if (scm->fp && send_fds)
err = unix_attach_fds(scm, skb);
@@ -1413,7 +1407,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
int namelen = 0; /* fake GCC */
int err;
unsigned hash;
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
long timeo;
struct scm_cookie tmp_scm;
int max_level;
@@ -1454,7 +1448,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (skb == NULL)
goto out;

- err = unix_scm_to_skb(siocb->scm, skb, true, false);
+ err = unix_scm_to_skb(siocb->scm, skb, true);
if (err < 0)
goto out_free;
max_level = err + 1;
@@ -1550,7 +1544,7 @@ restart:
unix_state_unlock(other);
other->sk_data_ready(other, len);
sock_put(other);
- scm_release(siocb->scm);
+ scm_destroy(siocb->scm);
return len;

out_unlock:
@@ -1560,8 +1554,7 @@ out_free:
out:
if (other)
sock_put(other);
- if (skb == NULL)
- scm_destroy(siocb->scm);
+ scm_destroy(siocb->scm);
return err;
}

@@ -1573,7 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sock *other = NULL;
int err, size;
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
int sent = 0;
struct scm_cookie tmp_scm;
bool fds_sent = false;
@@ -1638,11 +1631,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
size = min_t(int, size, skb_tailroom(skb));


- /* 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);
if (err < 0) {
kfree_skb(skb);
- goto out;
+ goto out_err;
}
max_level = err + 1;
fds_sent = true;
@@ -1650,7 +1643,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 +1660,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
sent += size;
}

- if (skb)
- scm_release(siocb->scm);
- else
- scm_destroy(siocb->scm);
+ scm_destroy(siocb->scm);
siocb->scm = NULL;

return sent;
@@ -1683,9 +1673,7 @@ pipe_err:
send_sig(SIGPIPE, current, 0);
err = -EPIPE;
out_err:
- if (skb == NULL)
- scm_destroy(siocb->scm);
-out:
+ scm_destroy(siocb->scm);
siocb->scm = NULL;
return sent ? : err;
}
@@ -1789,7 +1777,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
siocb->scm = &tmp_scm;
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
- scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
+ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
unix_set_secdata(siocb->scm, skb);

if (!(flags & MSG_PEEK)) {
@@ -1951,8 +1939,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
}
} else {
/* Copy credentials */
- scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid,
- UNIXCB(skb).cred);
+ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
check_creds = 1;
}

--
1.7.6
[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2011-09-03 06:35    [W:0.096 / U:0.164 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site