> On Oct 4, 2021, at 5:04 PM, Casey Schaufler <casey@xxxxxxxxxxxxxxxx> wrote: > > On 10/4/2021 4:25 PM, Jiang Wang wrote: >> Commit 94531cfcbe79 ("af_unix: Add unix_stream_proto for sockmap") >> sets unix domain socket peer state to TCP_CLOSE >> in unix_shutdown. This could happen when the local end is shutdown >> but the other end is not. Then the other end will get read or write >> failures which is not expected. >> >> Fix the issue by setting the local state to shutdown. >> >> Fixes: 94531cfcbe79 (af_unix: Add unix_stream_proto for sockmap) >> Suggested-by: Cong Wang <cong.wang@xxxxxxxxxxxxx> >> Reported-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> >> Signed-off-by: Jiang Wang <jiang.wang@xxxxxxxxxxxxx> > > This patch looks like it has fixed the problem. My test cases > are now getting expected results consistently. Please add any > or all of: > > Tested-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> > Reviewed-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> Acked-by: Song Liu <songliubraving@xxxxxx> > >> --- >> net/unix/af_unix.c | 9 +++++---- >> 1 file changed, 5 insertions(+), 4 deletions(-) >> >> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c >> index efac5989edb5..0878ab86597b 100644 >> --- a/net/unix/af_unix.c >> +++ b/net/unix/af_unix.c >> @@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode) >> >> unix_state_lock(sk); >> 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); >> if (other) >> sock_hold(other); >> @@ -2904,12 +2907,10 @@ static int unix_shutdown(struct socket *sock, int mode) >> other->sk_shutdown |= peer_mode; >> unix_state_unlock(other); >> other->sk_state_change(other); >> - if (peer_mode == SHUTDOWN_MASK) { >> + if (peer_mode == SHUTDOWN_MASK) >> sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); >> - other->sk_state = TCP_CLOSE; >> - } else if (peer_mode & RCV_SHUTDOWN) { >> + else if (peer_mode & RCV_SHUTDOWN) >> sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); >> - } >> } >> if (other) >> sock_put(other);