Can ->recvmsg() (or ->splice_read(), for that matter) overlap with ->release() of the socket it's reading from?
I'd always assumed that to be impossible, but we have this in unix_stream_read_generic(): redo: unix_state_lock(sk); if (sock_flag(sk, SOCK_DEAD)) { err = -ECONNRESET; goto unlock; } last = skb = skb_peek(&sk->sk_receive_queue); last_len = last ? last->len : 0; ... and sk comes from state->socket->sk, i.e. sock->sk of unix_stream_recvmsg() and unix_stream_splice_read(). IOW, the socket being read from. And SOCK_DEAD is only set by sock_orphan(), which means that socket would have to have gone through ->release(). What am I missing and how is that supposed to be triggered? Note that e.g. shutdown(2) doesn't set SOCK_DEAD - its effects are in ->sk_shutdown and the same unix_stream_read_generic() does check for those separately.