net: fix some potential race issues in the AF_UNIX code From: Paul Moore At least one user had reported some odd behavior with UNIX sockets which could be attributed to some _possible_ race conditions in unix_release_sock(). Reported-by: Konstantin Boyandin Reported-by: Jan Stancek Signed-off-by: Paul Moore --- net/unix/af_unix.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51be64f..886b8da 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -408,8 +408,10 @@ static int unix_release_sock(struct sock *sk, int embrion) skpair = unix_peer(sk); if (skpair != NULL) { - if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { - unix_state_lock(skpair); + unix_state_lock(skpair); + if (unix_our_peer(sk, skpair) && + (sk->sk_type == SOCK_STREAM || + sk->sk_type == SOCK_SEQPACKET)) { /* No more writes */ skpair->sk_shutdown = SHUTDOWN_MASK; if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) @@ -417,9 +419,10 @@ static int unix_release_sock(struct sock *sk, int embrion) unix_state_unlock(skpair); skpair->sk_state_change(skpair); sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); - } - sock_put(skpair); /* It may now die */ + } else + unix_state_unlock(skpair); unix_peer(sk) = NULL; + sock_put(skpair); /* It may now die */ } /* Try to flush out this socket. Throw out buffers at least */