Message ID | CA+icZUXULisfr6_EOrj8+q36UMo2mudcoJu3z0SX4T3x_OZQSg@mail.gmail.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
On Sat, Sep 3, 2011 at 3:47 PM, Sedat Dilek <sedat.dilek@googlemail.com> wrote: > 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. >> [...] > > 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! > [...] > 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 > 2nd run is fine, too. - Sedat - -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Sep 3, 2011 at 10:46 PM, Sedat Dilek <sedat.dilek@googlemail.com> wrote: > On Sat, Sep 3, 2011 at 3:47 PM, Sedat Dilek <sedat.dilek@googlemail.com> wrote: >> 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. >>> > [...] >> >> 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! >> > [...] >> 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 >> > > 2nd run is fine, too. > Thank you, will send a new patch later. > - Sedat - > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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