|
|
bd2f1e |
From d6f4bdc3bca4ddcdc60c0544d85ecf7670ee1c53 Mon Sep 17 00:00:00 2001
|
|
|
bd2f1e |
From: Duoming Zhou <duoming@zju.edu.cn>
|
|
|
bd2f1e |
Date: Sat, 26 Mar 2022 18:43:46 +0800
|
|
|
bd2f1e |
Subject: [PATCH] net/x25: Fix null-ptr-deref caused by x25_disconnect
|
|
|
bd2f1e |
Git-commit: 7781607938c8371d4c2b243527430241c62e39c2
|
|
|
bd2f1e |
Patch-mainline: v5.18-rc1
|
|
|
bd2f1e |
References: CVE-2022-1516 bsc#1199012
|
|
|
bd2f1e |
|
|
|
bd2f1e |
When the link layer is terminating, x25->neighbour will be set to NULL
|
|
|
bd2f1e |
in x25_disconnect(). As a result, it could cause null-ptr-deref bugs in
|
|
|
bd2f1e |
x25_sendmsg(),x25_recvmsg() and x25_connect(). One of the bugs is
|
|
|
bd2f1e |
shown below.
|
|
|
bd2f1e |
|
|
|
bd2f1e |
(Thread 1) | (Thread 2)
|
|
|
bd2f1e |
x25_link_terminated() | x25_recvmsg()
|
|
|
bd2f1e |
x25_kill_by_neigh() | ...
|
|
|
bd2f1e |
x25_disconnect() | lock_sock(sk)
|
|
|
bd2f1e |
... | ...
|
|
|
bd2f1e |
x25->neighbour = NULL //(1) |
|
|
|
bd2f1e |
... | x25->neighbour->extended //(2)
|
|
|
bd2f1e |
|
|
|
bd2f1e |
The code sets NULL to x25->neighbour in position (1) and dereferences
|
|
|
bd2f1e |
x25->neighbour in position (2), which could cause null-ptr-deref bug.
|
|
|
bd2f1e |
|
|
|
bd2f1e |
This patch adds lock_sock() in x25_kill_by_neigh() in order to synchronize
|
|
|
bd2f1e |
with x25_sendmsg(), x25_recvmsg() and x25_connect(). What`s more, the
|
|
|
bd2f1e |
sock held by lock_sock() is not NULL, because it is extracted from x25_list
|
|
|
bd2f1e |
and uses x25_list_lock to synchronize.
|
|
|
bd2f1e |
|
|
|
bd2f1e |
Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
|
|
|
bd2f1e |
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
|
|
|
bd2f1e |
Reviewed-by: Lin Ma <linma@zju.edu.cn>
|
|
|
bd2f1e |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
bd2f1e |
Signed-off-by: Denis Kirjanov <denis.kirjanov@suse.com>
|
|
|
bd2f1e |
---
|
|
|
bd2f1e |
net/x25/af_x25.c | 11 ++++++++---
|
|
|
bd2f1e |
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
bd2f1e |
|
|
|
bd2f1e |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
|
|
|
bd2f1e |
index b7e91af375a9..bdf6e80c8597 100644
|
|
|
bd2f1e |
--- a/net/x25/af_x25.c
|
|
|
bd2f1e |
+++ b/net/x25/af_x25.c
|
|
|
bd2f1e |
@@ -1789,10 +1789,15 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
|
|
|
bd2f1e |
|
|
|
bd2f1e |
write_lock_bh(&x25_list_lock);
|
|
|
bd2f1e |
|
|
|
bd2f1e |
- sk_for_each(s, &x25_list)
|
|
|
bd2f1e |
- if (x25_sk(s)->neighbour == nb)
|
|
|
bd2f1e |
+ sk_for_each(s, &x25_list) {
|
|
|
bd2f1e |
+ if (x25_sk(s)->neighbour == nb) {
|
|
|
bd2f1e |
+ write_unlock_bh(&x25_list_lock);
|
|
|
bd2f1e |
+ lock_sock(s);
|
|
|
bd2f1e |
x25_disconnect(s, ENETUNREACH, 0, 0);
|
|
|
bd2f1e |
-
|
|
|
bd2f1e |
+ release_sock(s);
|
|
|
bd2f1e |
+ write_lock_bh(&x25_list_lock);
|
|
|
bd2f1e |
+ }
|
|
|
bd2f1e |
+ }
|
|
|
bd2f1e |
write_unlock_bh(&x25_list_lock);
|
|
|
bd2f1e |
|
|
|
bd2f1e |
/* Remove any related forwards */
|
|
|
bd2f1e |
--
|
|
|
bd2f1e |
2.16.4
|
|
|
bd2f1e |
|