diff mbox series

[net] net/x25: Fix null-ptr-deref caused by x25_disconnect

Message ID 20220326065912.41077-1-duoming@zju.edu.cn (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net] net/x25: Fix null-ptr-deref caused by x25_disconnect | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 9 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Duoming Zhou March 26, 2022, 6:59 a.m. UTC
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@zju.edu.cn>
---
 net/x25/x25_subr.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Duoming Zhou March 26, 2022, 7:14 a.m. UTC | #1
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@zju.edu.cn>
> ---
>  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
diff mbox series

Patch

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);
 	}
 }