Commit f9390b24 authored by Vincent Whitchurch's avatar Vincent Whitchurch Committed by David S. Miller

af_unix: fix regression in read after shutdown

On kernels before v5.15, calling read() on a unix socket after
shutdown(SHUT_RD) or shutdown(SHUT_RDWR) would return the data
previously written or EOF.  But now, while read() after
shutdown(SHUT_RD) still behaves the same way, read() after
shutdown(SHUT_RDWR) always fails with -EINVAL.

This behaviour change was apparently inadvertently introduced as part of
a bug fix for a different regression caused by the commit adding sockmap
support to af_unix, commit 94531cfc ("af_unix: Add
unix_stream_proto for sockmap").  Those commits, for unclear reasons,
started setting the socket state to TCP_CLOSE on shutdown(SHUT_RDWR),
while this state change had previously only been done in
unix_release_sock().

Restore the original behaviour.  The sockmap tests in
tests/selftests/bpf continue to pass after this patch.

Fixes: d0c6416b ("unix: Fix an issue in unix_shutdown causing the other end read/write failures")
Link: https://lore.kernel.org/lkml/20211111140000.GA10779@axis.com/Signed-off-by: default avatarVincent Whitchurch <vincent.whitchurch@axis.com>
Tested-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent efaa9990
...@@ -2882,9 +2882,6 @@ static int unix_shutdown(struct socket *sock, int mode) ...@@ -2882,9 +2882,6 @@ static int unix_shutdown(struct socket *sock, int mode)
unix_state_lock(sk); unix_state_lock(sk);
sk->sk_shutdown |= mode; sk->sk_shutdown |= mode;
if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
mode == SHUTDOWN_MASK)
sk->sk_state = TCP_CLOSE;
other = unix_peer(sk); other = unix_peer(sk);
if (other) if (other)
sock_hold(other); sock_hold(other);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment