I am sorry, this patch has a problem. I will send the correct version later. > The previous commit 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when > x25 disconnect") adds decrement of refcount of x25->neighbour and sets > x25->neighbour to NULL in x25_disconnect(), but when the link layer is > terminating, it could cause null-ptr-deref bugs in x25_sendmsg(), > x25_recvmsg() and x25_connect(). One of the bugs is shown below. > > x25_link_terminated() | x25_recvmsg() > x25_kill_by_neigh() | ... > x25_disconnect() | lock_sock(sk) > ... | ... > x25->neighbour = NULL //(1) | > ... | x25->neighbour->extended //(2) > > We set NULL to x25->neighbour in position (1) and dereference > x25->neighbour in position (2), which could cause null-ptr-deref bug. > > This patch adds lock_sock(sk) in x25_disconnect() in order to synchronize > with x25_sendmsg(), x25_recvmsg() and x25_connect(). What`s more, the sk > held by lock_sock() is not NULL, because it is extracted from x25_list > and uses x25_list_lock to synchronize. > > Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect") > Signed-off-by: Duoming Zhou <duoming@xxxxxxxxxx> > --- > net/x25/x25_subr.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c > index 0285aaa1e93..4e19752bdd0 100644 > --- a/net/x25/x25_subr.c > +++ b/net/x25/x25_subr.c > @@ -360,7 +360,9 @@ void x25_disconnect(struct sock *sk, int reason, unsigned char cause, > if (x25->neighbour) { > read_lock_bh(&x25_list_lock); > x25_neigh_put(x25->neighbour); > + lock_sock(sk); > x25->neighbour = NULL; > + release_sock(sk); > read_unlock_bh(&x25_list_lock); > } > } > -- > 2.17.1