On Wed, 2011-09-07 at 09:45 +0200, Eric Dumazet wrote:
Le mercredi 07 septembre 2011 à 13:20 +0800, Yan, Zheng a écrit :
quoted
Is code like this OK? Thanks
---
if (sent + size < len) {
/* Only send the fds in the first buffer */
/* get additional ref if more skbs will be created */
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, true);
} else {
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, false);
ref_avail = false;
}
Whats wrong with using ref_avail in the unix_scm_to_skb() call itself ?
something like :
Eric,
Your updated patch looks good when I tested it on my side. It makes the
patch much more readable. If this patch looks good with you and Yan
Zheng, can you and Yan Zheng add your Signed-off-by to the patch?
Jiri, Sedat or Valdis, if you can verify that the patch fixed commit
0856a30409, that will be appreciated.
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Thanks.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,8 +1644,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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);gotoout;
On Wed, Sep 7, 2011 at 2:01 PM, Tim Chen [off-list ref] wrote:
quoted hunk
On Wed, 2011-09-07 at 09:45 +0200, Eric Dumazet wrote:
quoted
Le mercredi 07 septembre 2011 à 13:20 +0800, Yan, Zheng a écrit :
quoted
Is code like this OK? Thanks
---
if (sent + size < len) {
/* Only send the fds in the first buffer */
/* get additional ref if more skbs will be created */
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, true);
} else {
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, false);
ref_avail = false;
}
Whats wrong with using ref_avail in the unix_scm_to_skb() call itself ?
something like :
Eric,
Your updated patch looks good when I tested it on my side. It makes the
patch much more readable. If this patch looks good with you and Yan
Zheng, can you and Yan Zheng add your Signed-off-by to the patch?
Jiri, Sedat or Valdis, if you can verify that the patch fixed commit
0856a30409, that will be appreciated.
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Thanks.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
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 first buffer
+ * Last buffer can steal our references to pid/cred
+ */
+ steal_refs = (sent + size >= len);
+ err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, steal_refs);
if (err < 0) {
kfree_skb(skb);
goto out;
sent += size;
}
- if (skb)
+ if (steal_refs)
scm_release(siocb->scm);
else
scm_destroy(siocb->scm);
Replaced v2 with this patch (against next-20110831), I see now some
different call-traces which I did not see with v1 or v2.
Can't say if it's related to the new patch or not.
( dmesg attached. )
- Sedat -
On Wed, Sep 7, 2011 at 10:12 PM, Sedat Dilek [off-list ref] wrote:
On Wed, Sep 7, 2011 at 2:01 PM, Tim Chen [off-list ref] wrote:
quoted
On Wed, 2011-09-07 at 09:45 +0200, Eric Dumazet wrote:
quoted
Le mercredi 07 septembre 2011 à 13:20 +0800, Yan, Zheng a écrit :
quoted
Is code like this OK? Thanks
---
if (sent + size < len) {
/* Only send the fds in the first buffer */
/* get additional ref if more skbs will be created */
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, true);
} else {
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, false);
ref_avail = false;
}
Whats wrong with using ref_avail in the unix_scm_to_skb() call itself ?
something like :
Eric,
Your updated patch looks good when I tested it on my side. It makes the
patch much more readable. If this patch looks good with you and Yan
Zheng, can you and Yan Zheng add your Signed-off-by to the patch?
Jiri, Sedat or Valdis, if you can verify that the patch fixed commit
0856a30409, that will be appreciated.
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Thanks.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
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 first buffer
+ * Last buffer can steal our references to pid/cred
+ */
+ steal_refs = (sent + size >= len);
+ err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, steal_refs);
if (err < 0) {
kfree_skb(skb);
goto out;
sent += size;
}
- if (skb)
+ if (steal_refs)
scm_release(siocb->scm);
else
scm_destroy(siocb->scm);
Replaced v2 with this patch (against next-20110831), I see now some
different call-traces which I did not see with v1 or v2.
Can't say if it's related to the new patch or not.
( dmesg attached. )
- Sedat -
Call-traces seem to go away when adding "irqpoll" to Kernel command line.
( See dmesg_irqpoll.txt )
- Sedat -
From: Eric Dumazet <hidden> Date: 2011-09-07 21:26:12
Le mercredi 07 septembre 2011 à 05:01 -0700, Tim Chen a écrit :
On Wed, 2011-09-07 at 09:45 +0200, Eric Dumazet wrote:
quoted
Le mercredi 07 septembre 2011 à 13:20 +0800, Yan, Zheng a écrit :
quoted
Is code like this OK? Thanks
---
if (sent + size < len) {
/* Only send the fds in the first buffer */
/* get additional ref if more skbs will be created */
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, true);
} else {
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, false);
ref_avail = false;
}
Whats wrong with using ref_avail in the unix_scm_to_skb() call itself ?
something like :
Eric,
Your updated patch looks good when I tested it on my side. It makes the
patch much more readable. If this patch looks good with you and Yan
Zheng, can you and Yan Zheng add your Signed-off-by to the patch?
Jiri, Sedat or Valdis, if you can verify that the patch fixed commit
0856a30409, that will be appreciated.
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Yes, I'll try to cook a patch.
Thanks.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
On Wed, 2011-09-07 at 22:30 +0200, Sedat Dilek wrote:
quoted
Replaced v2 with this patch (against next-20110831), I see now some
different call-traces which I did not see with v1 or v2.
Can't say if it's related to the new patch or not.
( dmesg attached. )
- Sedat -
Call-traces seem to go away when adding "irqpoll" to Kernel command line.
( See dmesg_irqpoll.txt )
- Sedat -
Sedat,
The previous patch should use the new steal_refs to check for the
release of scm references in the error handling at the end. I've
updated the patch to take care of it. Hopefully the traces you see will
go away. Can you verify?
Thanks.
Tim
----
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all referentials to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
On Wed, 2011-09-07 at 22:30 +0200, Sedat Dilek wrote:
quoted
quoted
Replaced v2 with this patch (against next-20110831), I see now some
different call-traces which I did not see with v1 or v2.
Can't say if it's related to the new patch or not.
( dmesg attached. )
- Sedat -
Call-traces seem to go away when adding "irqpoll" to Kernel command line.
( See dmesg_irqpoll.txt )
- Sedat -
Sedat,
The previous patch should use the new steal_refs to check for the
release of scm references in the error handling at the end. I've
updated the patch to take care of it. Hopefully the traces you see will
go away. Can you verify?
Thanks.
Tim
----
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all referentials to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
err = -EPIPE; out_err:- if (skb == NULL)+ if (!steal_refs) scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
On Wed, 2011-09-07 at 14:06 -0700, Tim Chen wrote:
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
quoted
err = -EPIPE; out_err:- if (skb == NULL)+ if (!steal_refs) scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
Oops, I've forgotten to add Eric's previous Signed-off-by in my latest
patch log. David, please add that when you pick up the patch.
Once Yan Zheng added his sign off and Sedat tested the patch, I think it
will be good to go.
Thanks.
Tim
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
quoted
err = -EPIPE; out_err:- if (skb == NULL)+ if (!steal_refs) scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
From: Eric Dumazet <hidden> Date: 2011-09-08 05:59:40
Le mercredi 07 septembre 2011 à 14:06 -0700, Tim Chen a écrit :
quoted hunk
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
quoted
err = -EPIPE; out_err:- if (skb == NULL)+ if (!steal_refs) scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
I dont think this patch is good.
Sedat traces have nothing to do with af_unix.
Once unix_scm_to_skb() was called and successful, and steal_refs is true
our refs are attached to this skb. They will be released by
skb_free(skb). Same for fp : They either were sent in a previous skb or
this one.
This is why the "goto out;" was OK.
From: Eric Dumazet <hidden> Date: 2011-09-08 06:21:52
Le mercredi 07 septembre 2011 à 14:15 -0700, Tim Chen a écrit :
Oops, I've forgotten to add Eric's previous Signed-off-by in my latest
patch log. David, please add that when you pick up the patch.
Once Yan Zheng added his sign off and Sedat tested the patch, I think it
will be good to go.
Tim, as soon as you post another patch version, you must remove all
prior Signed-off-by, and only add yours.
So it was fine to do so.
By the way your last version introduce a new bug, so I would rather NACK
it ;)
Le mercredi 07 septembre 2011 à 14:06 -0700, Tim Chen a écrit :
quoted
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
quoted
err = -EPIPE; out_err:- if (skb == NULL)+ if (!steal_refs) scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
@@ -1642,11 +1644,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
I dont think this patch is good.
Sedat traces have nothing to do with af_unix.
Once unix_scm_to_skb() was called and successful, and steal_refs is true
our refs are attached to this skb. They will be released by
skb_free(skb). Same for fp : They either were sent in a previous skb or
this one.
This is why the "goto out;" was OK.
I don't think so. unix_scm_to_skb() calls unix_attach_fds(), it
always duplicates scm->fp.
Regards
On Thu, Sep 8, 2011 at 7:59 AM, Eric Dumazet [off-list ref] wrote:
Le mercredi 07 septembre 2011 à 14:06 -0700, Tim Chen a écrit :
quoted
On Thu, 2011-09-08 at 08:27 +0800, Yan, Zheng wrote:
quoted
quoted
err = -EPIPE;
out_err:
- if (skb == NULL)
+ if (!steal_refs)
scm_destroy(siocb->scm);
I think we should call scm_release() here in the case of
steal_refs == true. Otherwise siocb->scm->fp may leak.
Yan Zheng,
I've updated the patch. If it looks good to you now, can you add your
Signed-off-by to the patch. Pending Sedat's testing on this patch,
I think it is good to go.
Tim
---
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced a use-after-free bug.
The sent skbs from unix_stream_sendmsg could be consumed and destructed
by the receive side, removing all references to the credentials,
before the send side has finished sending out all
packets. However, send side could continue to consturct new packets in the
stream, using credentials that have lost its last reference and been
freed.
In this fix, we don't steal the reference to credentials we have obtained
in scm_send at beginning of unix_stream_sendmsg, till we've reached
the last packet. This fixes the problem in commit 0856a30409.
Signed-off-by: Tim Chen <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
sent += size;
}
- if (skb)
+ if (steal_refs)
scm_release(siocb->scm);
else
scm_destroy(siocb->scm);
@@ -1687,9 +1692,10 @@ pipe_err:
send_sig(SIGPIPE, current, 0);
err = -EPIPE;
out_err:
- if (skb == NULL)
+ if (steal_refs)
+ scm_release(siocb->scm);
+ else
scm_destroy(siocb->scm);
-out:
siocb->scm = NULL;
return sent ? : err;
}
I dont think this patch is good.
Sedat traces have nothing to do with af_unix.
Once unix_scm_to_skb() was called and successful, and steal_refs is true
our refs are attached to this skb. They will be released by
skb_free(skb). Same for fp : They either were sent in a previous skb or
this one.
This is why the "goto out;" was OK.
Good morning,
/me sees so many patches :-).
Yes, I guess the patch by Eric has nothing to do with seen
call-traces, adding "irqpoll" to Kernel command line seems to fix them
(my uptime: approx. 10:30, Eric's proposal patch in my last
patch-series is attached).
- Sedat -
From: Eric Dumazet <hidden> Date: 2011-09-08 07:12:06
Le jeudi 08 septembre 2011 à 14:22 +0800, Yan, Zheng a écrit :
I don't think so. unix_scm_to_skb() calls unix_attach_fds(), it
always duplicates scm->fp.
What a mess. This code is a nightmare.
Part of the mess comes from scm_destroy() and scm_release() duplication.
We should have scm_destroy() only, as before, and NULLify scm->pid/cred
in unix_scm_to_skb() when we steal references.
It makes more sense and keeps things clearer.
include/net/scm.h | 9 ---------
net/unix/af_unix.c | 27 +++++++++++++++------------
2 files changed, 15 insertions(+), 21 deletions(-)
@@ -1638,8 +1642,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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);gotoout;
Le jeudi 08 septembre 2011 à 14:22 +0800, Yan, Zheng a écrit :
quoted
I don't think so. unix_scm_to_skb() calls unix_attach_fds(), it
always duplicates scm->fp.
What a mess. This code is a nightmare.
Part of the mess comes from scm_destroy() and scm_release() duplication.
We should have scm_destroy() only, as before, and NULLify scm->pid/cred
in unix_scm_to_skb() when we steal references.
It makes more sense and keeps things clearer.
include/net/scm.h | 9 ---------
net/unix/af_unix.c | 27 +++++++++++++++------------
2 files changed, 15 insertions(+), 21 deletions(-)
@@ -1638,8 +1642,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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);gotoout;
@@ -1638,11 +1642,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
Le jeudi 08 septembre 2011 à 14:22 +0800, Yan, Zheng a écrit :
quoted
I don't think so. unix_scm_to_skb() calls unix_attach_fds(), it
always duplicates scm->fp.
What a mess. This code is a nightmare.
Part of the mess comes from scm_destroy() and scm_release() duplication.
We should have scm_destroy() only, as before, and NULLify scm->pid/cred
in unix_scm_to_skb() when we steal references.
This patch works for me. I haven't tried the out_err fixup from the
followup, but I assume I won't spot a difference as those are fail paths
anyway...
thanks,
--
js
On Thu, Sep 8, 2011 at 9:56 AM, Jiri Slaby [off-list ref] wrote:
On 09/08/2011 09:11 AM, Eric Dumazet wrote:
quoted
Le jeudi 08 septembre 2011 à 14:22 +0800, Yan, Zheng a écrit :
quoted
I don't think so. unix_scm_to_skb() calls unix_attach_fds(), it
always duplicates scm->fp.
What a mess. This code is a nightmare.
Part of the mess comes from scm_destroy() and scm_release() duplication.
We should have scm_destroy() only, as before, and NULLify scm->pid/cred
in unix_scm_to_skb() when we steal references.
This patch works for me. I haven't tried the out_err fixup from the
followup, but I assume I won't spot a difference as those are fail paths
anyway...
thanks,
--
js
I have tested the same patch here (before shopping, but can test the
"final" patch, too.).
- Sedat -
From: Eric Dumazet <hidden> Date: 2011-09-08 13:21:39
Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :
I have tested this fixup patch on i386.
Can we have a separate patch with corrected descriptive text?
Thanks to all involved people.
Here it is :
[PATCH net-next v3] af_unix: Fix use-after-free crashes
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug.
We are allowed to steal the references to pid/cred only in the last skb
sent from unix_stream_sendmsg(), because first skbs might be consumed by
the receiver before we finish our sendmsg() call.
Remove scm_release() helper, since its cleaner to clear pid/cred fields
in unix_scm_to_skb() when we steal them.
Based on prior patches from Yan Zheng and Tim Chen
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
include/net/scm.h | 9 ---------
net/unix/af_unix.c | 32 +++++++++++++++++---------------
2 files changed, 17 insertions(+), 24 deletions(-)
@@ -1638,11 +1642,14 @@ 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 first buffer+*Lastbuffercanstealourreferencestopid/cred+*/+steal_refs=(sent+size>=len);+err=unix_scm_to_skb(siocb->scm,skb,!fds_sent,steal_refs);if(err<0){kfree_skb(skb);-gotoout;+gotoout_err;}max_level=err+1;fds_sent=true;
From: Eric Dumazet <hidden> Date: 2011-09-08 13:28:15
Le mercredi 07 septembre 2011 à 23:26 +0200, Eric Dumazet a écrit :
Le mercredi 07 septembre 2011 à 05:01 -0700, Tim Chen a écrit :
quoted
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Yes, I'll try to cook a patch.
Thinking a bit more on this issue, I really believe we should not stick
pid/cred in skbs sent from a write() system call.
That would break following use case :
An application uses a write(fd) and expects a receiver using recvmsg()
to get process credentials (SCM_CREDENTIALS)
This is currently working, but not documented (man unix says ancillary
data are sent with sendmsg())
If everybody agrees, I can send a patch for this : This would speedup
write()/read() af_unix by an order of magnitude.
On Thu, 2011-09-08 at 15:21 +0200, Eric Dumazet wrote:
Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :
quoted
I have tested this fixup patch on i386.
Can we have a separate patch with corrected descriptive text?
Thanks to all involved people.
Here it is :
[PATCH net-next v3] af_unix: Fix use-after-free crashes
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug.
We are allowed to steal the references to pid/cred only in the last skb
sent from unix_stream_sendmsg(), because first skbs might be consumed by
the receiver before we finish our sendmsg() call.
Remove scm_release() helper, since its cleaner to clear pid/cred fields
in unix_scm_to_skb() when we steal them.
Based on prior patches from Yan Zheng and Tim Chen
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
On Thu, 2011-09-08 at 15:28 +0200, Eric Dumazet wrote:
Le mercredi 07 septembre 2011 à 23:26 +0200, Eric Dumazet a écrit :
quoted
Le mercredi 07 septembre 2011 à 05:01 -0700, Tim Chen a écrit :
quoted
quoted
Eric, are you planning to do a fast path patch that doesn't do pid ref
for the case where CONFIG_PID_NS is not set?
Yes, I'll try to cook a patch.
Thinking a bit more on this issue, I really believe we should not stick
pid/cred in skbs sent from a write() system call.
I prefer this approach too.
That would break following use case :
An application uses a write(fd) and expects a receiver using recvmsg()
to get process credentials (SCM_CREDENTIALS)
This is currently working, but not documented (man unix says ancillary
data are sent with sendmsg())
If everybody agrees, I can send a patch for this : This would speedup
write()/read() af_unix by an order of magnitude.
Looking forward to the patch. This should improve the scalability of
af_unix.
Tim
From: Eric Dumazet <hidden> Date: 2011-09-09 05:06:26
Le jeudi 08 septembre 2011 à 02:24 -0700, Tim Chen a écrit :
Looking forward to the patch. This should improve the scalability of
af_unix.
Here it is, based on top on previous one [af_unix: Fix use-after-free
crashes]
Thanks
[PATCH net-next] af_unix: dont send SCM_CREDENTIALS by default
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
# Events: 154K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................. ...................................
#
10.40% hackbench [kernel.kallsyms] [k] put_pid
8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
1.75% hackbench [kernel.kallsyms] [k] fget_light
1.51% hackbench [kernel.kallsyms] [k] __mutex_lock_interruptible_slowpath
1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call.
Performance boost in hackbench : more than 50% gain on a 16 thread
machine (2 quad-core cpus, 2 threads per core)
hackbench 20 thread 2000
4.224 sec instead of 9.102 sec
Signed-off-by: Eric Dumazet <redacted>
---
include/net/scm.h | 11 +----------
net/core/scm.c | 10 ++++++----
net/netlink/af_netlink.c | 5 ++---
net/unix/af_unix.c | 9 +++++----
4 files changed, 14 insertions(+), 21 deletions(-)
From: Eric Dumazet <hidden> Date: 2011-09-09 06:51:48
Le jeudi 08 septembre 2011 à 01:37 -0700, Tim Chen a écrit :
On Thu, 2011-09-08 at 15:21 +0200, Eric Dumazet wrote:
quoted
Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :
quoted
I have tested this fixup patch on i386.
Can we have a separate patch with corrected descriptive text?
Thanks to all involved people.
Here it is :
[PATCH net-next v3] af_unix: Fix use-after-free crashes
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug.
We are allowed to steal the references to pid/cred only in the last skb
sent from unix_stream_sendmsg(), because first skbs might be consumed by
the receiver before we finish our sendmsg() call.
Remove scm_release() helper, since its cleaner to clear pid/cred fields
in unix_scm_to_skb() when we steal them.
Based on prior patches from Yan Zheng and Tim Chen
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
Thanks.
Acked-by: Tim Chen <redacted>
Now we have to fix a bug in unix_stream_recvmsg() as well.
consume_skb() call actually releases pid/cred references, and we can use
them after their eventual freeing.
Keep also in mind that receiver can provides a too short user buffer,
and skb can be put back to head of sk_receive_queue
Tim, your 0856a304091b33 commit introduced a lot of bugs, I was right
asking a revert.
If we revert your patch, my litle patch (af_unix: dont send
SCM_CREDENTIALS by default) is enough to solve performance problems.
From: Eric Dumazet <hidden> Date: 2011-09-09 08:15:39
Le vendredi 09 septembre 2011 à 08:51 +0200, Eric Dumazet a écrit :
Now we have to fix a bug in unix_stream_recvmsg() as well.
consume_skb() call actually releases pid/cred references, and we can use
them after their eventual freeing.
Keep also in mind that receiver can provides a too short user buffer,
and skb can be put back to head of sk_receive_queue
Here is the patch to address this point.
Apply it after (af_unix: Fix use-after-free crashes)
I can make a combo patch once everybody agrees.
[PATCH net-next] af_unix: fix use after free in unix_stream_recvmsg()
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug in unix_stream_recvmsg().
We should call consume_skb(skb) only after our possible use of pid/cred.
Signed-off-by: Eric Dumazet <redacted>
---
net/unix/af_unix.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
@@ -1984,13 +1986,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,/* put the skb back if we didn't use it up.. */if(skb->len){skb_queue_head(&sk->sk_receive_queue,skb);+skb=NULL;break;}-consume_skb(skb);--if(siocb->scm->fp)+if(UNIXCB(skb).pid||siocb->scm->fp)break;+consume_skb(skb);+skb=NULL;}else{/* It is questionable, see note in unix_dgram_recvmsg.*/
@@ -1999,12 +2002,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,/* put message back and return */skb_queue_head(&sk->sk_receive_queue,skb);+skb=NULL;break;}}while(size);mutex_unlock(&u->readlock);scm_recv(sock,msg,siocb->scm,flags);+consume_skb(skb);out:returncopied?:err;}
On Fri, 2011-09-09 at 09:58 +0200, Eric Dumazet wrote:
quoted hunk
Le vendredi 09 septembre 2011 à 08:51 +0200, Eric Dumazet a écrit :
quoted
Now we have to fix a bug in unix_stream_recvmsg() as well.
consume_skb() call actually releases pid/cred references, and we can use
them after their eventual freeing.
Keep also in mind that receiver can provides a too short user buffer,
and skb can be put back to head of sk_receive_queue
Here is the patch to address this point.
Apply it after (af_unix: Fix use-after-free crashes)
I can make a combo patch once everybody agrees.
[PATCH net-next] af_unix: fix use after free in unix_stream_recvmsg()
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug in unix_stream_recvmsg().
We should call consume_skb(skb) only after our possible use of pid/cred.
Signed-off-by: Eric Dumazet <redacted>
---
net/unix/af_unix.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
@@ -1984,13 +1986,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,/* put the skb back if we didn't use it up.. */if(skb->len){skb_queue_head(&sk->sk_receive_queue,skb);+skb=NULL;break;}-consume_skb(skb);--if(siocb->scm->fp)+if(UNIXCB(skb).pid||siocb->scm->fp)break;+consume_skb(skb);+skb=NULL;}else{/* It is questionable, see note in unix_dgram_recvmsg.*/
@@ -1999,12 +2002,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,/* put message back and return */skb_queue_head(&sk->sk_receive_queue,skb);+skb=NULL;break;}}while(size);mutex_unlock(&u->readlock);scm_recv(sock,msg,siocb->scm,flags);+consume_skb(skb);out:returncopied?:err;}
On Fri, 2011-09-09 at 08:51 +0200, Eric Dumazet wrote:
Le jeudi 08 septembre 2011 à 01:37 -0700, Tim Chen a écrit :
quoted
On Thu, 2011-09-08 at 15:21 +0200, Eric Dumazet wrote:
quoted
Le jeudi 08 septembre 2011 à 11:59 +0200, Sedat Dilek a écrit :
quoted
I have tested this fixup patch on i386.
Can we have a separate patch with corrected descriptive text?
Thanks to all involved people.
Here it is :
[PATCH net-next v3] af_unix: Fix use-after-free crashes
Commit 0856a30409 (Scm: Remove unnecessary pid & credential references
in Unix socket's send and receive path) introduced an use-after-free
bug.
We are allowed to steal the references to pid/cred only in the last skb
sent from unix_stream_sendmsg(), because first skbs might be consumed by
the receiver before we finish our sendmsg() call.
Remove scm_release() helper, since its cleaner to clear pid/cred fields
in unix_scm_to_skb() when we steal them.
Based on prior patches from Yan Zheng and Tim Chen
Signed-off-by: Eric Dumazet <redacted>
Reported-by: Jiri Slaby <redacted>
Tested-by: Sedat Dilek <redacted>
Tested-by: Valdis Kletnieks <redacted>
---
Thanks.
Acked-by: Tim Chen <redacted>
Now we have to fix a bug in unix_stream_recvmsg() as well.
Thanks for your careful review to catch the bugs. Wish I had thought
about the stream msg case more in my original patch.
consume_skb() call actually releases pid/cred references, and we can use
them after their eventual freeing.
Keep also in mind that receiver can provides a too short user buffer,
and skb can be put back to head of sk_receive_queue
Tim, your 0856a304091b33 commit introduced a lot of bugs, I was right
asking a revert.
If we revert your patch, my litle patch (af_unix: dont send
SCM_CREDENTIALS by default) is enough to solve performance problems.
But the regression where we do send SCM_CREDENTIALS is not addressed,
right? I don't mind reverting my patch if there's a better solution.
Tim
On Fri, 2011-09-09 at 07:06 +0200, Eric Dumazet wrote:
Le jeudi 08 septembre 2011 à 02:24 -0700, Tim Chen a écrit :
quoted
Looking forward to the patch. This should improve the scalability of
af_unix.
Here it is, based on top on previous one [af_unix: Fix use-after-free
crashes]
Thanks
[PATCH net-next] af_unix: dont send SCM_CREDENTIALS by default
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
# Events: 154K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................. ...................................
#
10.40% hackbench [kernel.kallsyms] [k] put_pid
8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
1.75% hackbench [kernel.kallsyms] [k] fget_light
1.51% hackbench [kernel.kallsyms] [k] __mutex_lock_interruptible_slowpath
1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call.
Performance boost in hackbench : more than 50% gain on a 16 thread
machine (2 quad-core cpus, 2 threads per core)
hackbench 20 thread 2000
4.224 sec instead of 9.102 sec
Signed-off-by: Eric Dumazet <redacted>
This speeds up the case where we're not passing SCM_CREDENTIALS nicely.
Acked-by: Tim Chen <redacted>
From: Eric Dumazet <hidden> Date: 2011-09-19 04:29:04
Le dimanche 18 septembre 2011 à 21:07 -0400, David Miller a écrit :
Eric, please respin your patches against current net-next, thanks!
Sure, here it is :
Its a bit different, so I didnt add Tim 'Acked-by'
[PATCH net-next] af_unix: dont send SCM_CREDENTIALS by default
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
# Events: 154K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................. .........................
#
10.40% hackbench [kernel.kallsyms] [k] put_pid
8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
1.75% hackbench [kernel.kallsyms] [k] fget_light
1.51% hackbench [kernel.kallsyms] [k]
__mutex_lock_interruptible_slowpath
1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call.
Performance boost in hackbench : more than 50% gain on a 16 thread
machine (2 quad-core cpus, 2 threads per core)
hackbench 20 thread 2000
4.228 sec instead of 9.102 sec
Signed-off-by: Eric Dumazet <redacted>
---
include/net/scm.h | 5 ++---
net/core/scm.c | 10 ++++++----
net/netlink/af_netlink.c | 5 ++---
net/unix/af_unix.c | 4 +++-
4 files changed, 13 insertions(+), 11 deletions(-)
From: Eric Dumazet <hidden> Date: 2011-09-19 15:01:59
Le lundi 19 septembre 2011 à 06:28 +0200, Eric Dumazet a écrit :
Le dimanche 18 septembre 2011 à 21:07 -0400, David Miller a écrit :
quoted
Eric, please respin your patches against current net-next, thanks!
Sure, here it is :
Its a bit different, so I didnt add Tim 'Acked-by'
[PATCH net-next] af_unix: dont send SCM_CREDENTIALS by default
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call.
I appears udevd is such an application.
I am trying testing SOCK_PASSCRED flag and include SCM_CREDENTIALS if
set.
From: Eric Dumazet <hidden> Date: 2011-09-19 15:52:19
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
# Events: 154K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................. .........................
#
10.40% hackbench [kernel.kallsyms] [k] put_pid
8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
1.75% hackbench [kernel.kallsyms] [k] fget_light
1.51% hackbench [kernel.kallsyms] [k]
__mutex_lock_interruptible_slowpath
1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call, and receiver not using SO_PASSCRED
socket option.
If SOCK_PASSCRED is set on source or destination socket, we still
include credentials for mere write() syscalls.
Performance boost in hackbench : more than 50% gain on a 16 thread
machine (2 quad-core cpus, 2 threads per core)
hackbench 20 thread 2000
4.228 sec instead of 9.102 sec
Signed-off-by: Eric Dumazet <redacted>
---
net/netlink/af_netlink.c net/unix/af_unix.c|diffstat -p1 -w70
include/net/scm.h | 5 ++---
net/core/scm.c | 10 ++++++----
net/netlink/af_netlink.c | 5 ++---
net/unix/af_unix.c | 24 +++++++++++++++++++++++--
4 files changed, 33 insertions(+), 11 deletions(-)
On Mon, 2011-09-19 at 17:52 +0200, Eric Dumazet wrote:
Since commit 7361c36c5224 (af_unix: Allow credentials to work across
user and pid namespaces) af_unix performance dropped a lot.
This is because we now take a reference on pid and cred in each write(),
and release them in read(), usually done from another process,
eventually from another cpu. This triggers false sharing.
# Events: 154K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................. .........................
#
10.40% hackbench [kernel.kallsyms] [k] put_pid
8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
1.75% hackbench [kernel.kallsyms] [k] fget_light
1.51% hackbench [kernel.kallsyms] [k]
__mutex_lock_interruptible_slowpath
1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call, and receiver not using SO_PASSCRED
socket option.
If SOCK_PASSCRED is set on source or destination socket, we still
include credentials for mere write() syscalls.
Performance boost in hackbench : more than 50% gain on a 16 thread
machine (2 quad-core cpus, 2 threads per core)
hackbench 20 thread 2000
4.228 sec instead of 9.102 sec
Signed-off-by: Eric Dumazet <redacted>
---
Do we have to worry about the case where peer socket changes its flag
to SOCK_PASSCRED while packets are in flight? If there isn't such
pathological use case, the patch looks fine to me.
Acked-by: Tim Chen <redacted>
This patch includes SCM_CREDENTIALS information in a af_unix message/skb
only if requested by the sender, [man 7 unix for details how to include
ancillary data using sendmsg() system call]
Note: This might break buggy applications that expected SCM_CREDENTIAL
from an unaware write() system call, and receiver not using SO_PASSCRED
socket option.
If SOCK_PASSCRED is set on source or destination socket, we still
include credentials for mere write() syscalls.
I thought a lot about this and I think we should be able to get away
with this trick, so I've added this patch to net-next, thanks!