| From 7d758add176d3e35f202b92886061f7323576d41 Mon Sep 17 00:00:00 2001 |
| From: "Eric W. Biederman" <ebiederm@xmission.com> |
| Date: Wed, 3 Apr 2013 16:14:47 +0000 |
| Subject: af_unix: If we don't care about credentials coallesce all messages |
| |
| |
| From: "Eric W. Biederman" <ebiederm@xmission.com> |
| |
| [ Upstream commit 0e82e7f6dfeec1013339612f74abc2cdd29d43d2 ] |
| |
| It was reported that the following LSB test case failed |
| https://lsbbugs.linuxfoundation.org/attachment.cgi?id=2144 because we |
| were not coallescing unix stream messages when the application was |
| expecting us to. |
| |
| The problem was that the first send was before the socket was accepted |
| and thus sock->sk_socket was NULL in maybe_add_creds, and the second |
| send after the socket was accepted had a non-NULL value for sk->socket |
| and thus we could tell the credentials were not needed so we did not |
| bother. |
| |
| The unnecessary credentials on the first message cause |
| unix_stream_recvmsg to start verifying that all messages had the same |
| credentials before coallescing and then the coallescing failed because |
| the second message had no credentials. |
| |
| Ignoring credentials when we don't care in unix_stream_recvmsg fixes a |
| long standing pessimization which would fail to coallesce messages when |
| reading from a unix stream socket if the senders were different even if |
| we did not care about their credentials. |
| |
| I have tested this and verified that the in the LSB test case mentioned |
| above that the messages do coallesce now, while the were failing to |
| coallesce without this change. |
| |
| Reported-by: Karel Srot <ksrot@redhat.com> |
| Reported-by: Ding Tianhong <dingtianhong@huawei.com> |
| Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/unix/af_unix.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/net/unix/af_unix.c |
| +++ b/net/unix/af_unix.c |
| @@ -1986,7 +1986,7 @@ again: |
| if ((UNIXCB(skb).pid != siocb->scm->pid) || |
| (UNIXCB(skb).cred != siocb->scm->cred)) |
| break; |
| - } else { |
| + } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
| /* Copy credentials */ |
| scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); |
| check_creds = 1; |