CVE-2022-48721
Publication date:
20/06/2024
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net/smc: Forward wakeup to smc socket waitqueue after fallback<br />
<br />
When we replace TCP with SMC and a fallback occurs, there may be<br />
some socket waitqueue entries remaining in smc socket->wq, such<br />
as eppoll_entries inserted by userspace applications.<br />
<br />
After the fallback, data flows over TCP/IP and only clcsocket->wq<br />
will be woken up. Applications can&#39;t be notified by the entries<br />
which were inserted in smc socket->wq before fallback. So we need<br />
a mechanism to wake up smc socket->wq at the same time if some<br />
entries remaining in it.<br />
<br />
The current workaround is to transfer the entries from smc socket->wq<br />
to clcsock->wq during the fallback. But this may cause a crash<br />
like this:<br />
<br />
general protection fault, probably for non-canonical address 0xdead000000000100: 0000 [#1] PREEMPT SMP PTI<br />
CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Tainted: G E 5.16.0+ #107<br />
RIP: 0010:__wake_up_common+0x65/0x170<br />
Call Trace:<br />
<br />
__wake_up_common_lock+0x7a/0xc0<br />
sock_def_readable+0x3c/0x70<br />
tcp_data_queue+0x4a7/0xc40<br />
tcp_rcv_established+0x32f/0x660<br />
? sk_filter_trim_cap+0xcb/0x2e0<br />
tcp_v4_do_rcv+0x10b/0x260<br />
tcp_v4_rcv+0xd2a/0xde0<br />
ip_protocol_deliver_rcu+0x3b/0x1d0<br />
ip_local_deliver_finish+0x54/0x60<br />
ip_local_deliver+0x6a/0x110<br />
? tcp_v4_early_demux+0xa2/0x140<br />
? tcp_v4_early_demux+0x10d/0x140<br />
ip_sublist_rcv_finish+0x49/0x60<br />
ip_sublist_rcv+0x19d/0x230<br />
ip_list_rcv+0x13e/0x170<br />
__netif_receive_skb_list_core+0x1c2/0x240<br />
netif_receive_skb_list_internal+0x1e6/0x320<br />
napi_complete_done+0x11d/0x190<br />
mlx5e_napi_poll+0x163/0x6b0 [mlx5_core]<br />
__napi_poll+0x3c/0x1b0<br />
net_rx_action+0x27c/0x300<br />
__do_softirq+0x114/0x2d2<br />
irq_exit_rcu+0xb4/0xe0<br />
common_interrupt+0xba/0xe0<br />
<br />
<br />
<br />
The crash is caused by privately transferring waitqueue entries from<br />
smc socket->wq to clcsock->wq. The owners of these entries, such as<br />
epoll, have no idea that the entries have been transferred to a<br />
different socket wait queue and still use original waitqueue spinlock<br />
(smc socket->wq.wait.lock) to make the entries operation exclusive,<br />
but it doesn&#39;t work. The operations to the entries, such as removing<br />
from the waitqueue (now is clcsock->wq after fallback), may cause a<br />
crash when clcsock waitqueue is being iterated over at the moment.<br />
<br />
This patch tries to fix this by no longer transferring wait queue<br />
entries privately, but introducing own implementations of clcsock&#39;s<br />
callback functions in fallback situation. The callback functions will<br />
forward the wakeup to smc socket->wq if clcsock->wq is actually woken<br />
up and smc socket->wq has remaining entries.
Severity CVSS v4.0: Pending analysis
Last modification:
01/10/2025