提交 c1f8731c 编写于 作者: D Duoming Zhou 提交者: Zheng Zengkai

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

stable inclusion
from stable-v5.10.110
commit 5c94b6205e87411dbe9dc1ca088eb36b8837fb47
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5661B
CVE: CVE-2022-1516

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5c94b6205e87411dbe9dc1ca088eb36b8837fb47

--------------------------------

[ Upstream commit 77816079 ]

When the link layer is terminating, x25->neighbour will be set to NULL
in x25_disconnect(). As a result, it could cause null-ptr-deref bugs in
x25_sendmsg(),x25_recvmsg() and x25_connect(). One of the bugs is
shown below.

    (Thread 1)                 |  (Thread 2)
x25_link_terminated()          | x25_recvmsg()
 x25_kill_by_neigh()           |  ...
  x25_disconnect()             |  lock_sock(sk)
   ...                         |  ...
   x25->neighbour = NULL //(1) |
   ...                         |  x25->neighbour->extended //(2)

The code sets NULL to x25->neighbour in position (1) and dereferences
x25->neighbour in position (2), which could cause null-ptr-deref bug.

This patch adds lock_sock() in x25_kill_by_neigh() in order to synchronize
with x25_sendmsg(), x25_recvmsg() and x25_connect(). What`s more, the
sock held by lock_sock() is not NULL, because it is extracted from x25_list
and uses x25_list_lock to synchronize.

Fixes: 4becb7ee ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
Signed-off-by: NDuoming Zhou <duoming@zju.edu.cn>
Reviewed-by: NLin Ma <linma@zju.edu.cn>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NBaisong Zhong <zhongbaisong@huawei.com>
Reviewed-by: NYue Haibing <yuehaibing@huawei.com>
Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 5cbc0d0f
...@@ -1775,10 +1775,15 @@ void x25_kill_by_neigh(struct x25_neigh *nb) ...@@ -1775,10 +1775,15 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
write_lock_bh(&x25_list_lock); write_lock_bh(&x25_list_lock);
sk_for_each(s, &x25_list) sk_for_each(s, &x25_list) {
if (x25_sk(s)->neighbour == nb) if (x25_sk(s)->neighbour == nb) {
write_unlock_bh(&x25_list_lock);
lock_sock(s);
x25_disconnect(s, ENETUNREACH, 0, 0); x25_disconnect(s, ENETUNREACH, 0, 0);
release_sock(s);
write_lock_bh(&x25_list_lock);
}
}
write_unlock_bh(&x25_list_lock); write_unlock_bh(&x25_list_lock);
/* Remove any related forwards */ /* Remove any related forwards */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册