Skip to content

Commit 43fb2b3

Browse files
q2venkuba-moo
authored andcommitted
af_unix: Allow passing cred for embryo without SO_PASSCRED/SO_PASSPIDFD.
Before the cited commit, the kernel unconditionally embedded SCM credentials to skb for embryo sockets even when both the sender and listener disabled SO_PASSCRED and SO_PASSPIDFD. Now, the credentials are added to skb only when configured by the sender or the listener. However, as reported in the link below, it caused a regression for some programs that assume credentials are included in every skb, but sometimes not now. The only problematic scenario would be that a socket starts listening before setting the option. Then, there will be 2 types of non-small race window, where a client can send skb without credentials, which the peer receives as an "invalid" message (and aborts the connection it seems ?): Client Server ------ ------ s1.listen() <-- No SO_PASS{CRED,PIDFD} s2.connect() s2.send() <-- w/o cred s1.setsockopt(SO_PASS{CRED,PIDFD}) s2.send() <-- w/ cred or Client Server ------ ------ s1.listen() <-- No SO_PASS{CRED,PIDFD} s2.connect() s2.send() <-- w/o cred s3, _ = s1.accept() <-- Inherit cred options s2.send() <-- w/o cred but not set yet s3.setsockopt(SO_PASS{CRED,PIDFD}) s2.send() <-- w/ cred It's unfortunate that buggy programs depend on the behaviour, but let's restore the previous behaviour. Fixes: 3f84d57 ("af_unix: Inherit sk_flags at connect().") Reported-by: Jacek Łuczak <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Kuniyuki Iwashima <[email protected]> Tested-by: Christian Heusel <[email protected]> Tested-by: André Almeida <[email protected]> Tested-by: Jacek Łuczak <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent b3979e3 commit 43fb2b3

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

net/unix/af_unix.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,8 @@ static void unix_maybe_add_creds(struct sk_buff *skb, const struct sock *sk,
19711971
if (UNIXCB(skb).pid)
19721972
return;
19731973

1974-
if (unix_may_passcred(sk) || unix_may_passcred(other)) {
1974+
if (unix_may_passcred(sk) || unix_may_passcred(other) ||
1975+
!other->sk_socket) {
19751976
UNIXCB(skb).pid = get_pid(task_tgid(current));
19761977
current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
19771978
}

0 commit comments

Comments
 (0)