CVE-2024-56674
Publication date:
27/12/2024
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
virtio_net: correct netdev_tx_reset_queue() invocation point<br />
<br />
When virtnet_close is followed by virtnet_open, some TX completions can<br />
possibly remain unconsumed, until they are finally processed during the<br />
first NAPI poll after the netdev_tx_reset_queue(), resulting in a crash<br />
[1]. Commit b96ed2c97c79 ("virtio_net: move netdev_tx_reset_queue() call<br />
before RX napi enable") was not sufficient to eliminate all BQL crash<br />
cases for virtio-net.<br />
<br />
This issue can be reproduced with the latest net-next master by running:<br />
`while :; do ip l set DEV down; ip l set DEV up; done` under heavy network<br />
TX load from inside the machine.<br />
<br />
netdev_tx_reset_queue() can actually be dropped from virtnet_open path;<br />
the device is not stopped in any case. For BQL core part, it&#39;s just like<br />
traffic nearly ceases to exist for some period. For stall detector added<br />
to BQL, even if virtnet_close could somehow lead to some TX completions<br />
delayed for long, followed by virtnet_open, we can just take it as stall<br />
as mentioned in commit 6025b9135f7a ("net: dqs: add NIC stall detector<br />
based on BQL"). Note also that users can still reset stall_max via sysfs.<br />
<br />
So, drop netdev_tx_reset_queue() from virtnet_enable_queue_pair(). This<br />
eliminates the BQL crashes. As a result, netdev_tx_reset_queue() is now<br />
explicitly required in freeze/restore path. This patch adds it to<br />
immediately after free_unused_bufs(), following the rule of thumb:<br />
netdev_tx_reset_queue() should follow any SKB freeing not followed by<br />
netdev_tx_completed_queue(). This seems the most consistent and<br />
streamlined approach, and now netdev_tx_reset_queue() runs whenever<br />
free_unused_bufs() is done.<br />
<br />
[1]:<br />
------------[ cut here ]------------<br />
kernel BUG at lib/dynamic_queue_limits.c:99!<br />
Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI<br />
CPU: 7 UID: 0 PID: 1598 Comm: ip Tainted: G N 6.12.0net-next_main+ #2<br />
Tainted: [N]=TEST<br />
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), \<br />
BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014<br />
RIP: 0010:dql_completed+0x26b/0x290<br />
Code: b7 c2 49 89 e9 44 89 da 89 c6 4c 89 d7 e8 ed 17 47 00 58 65 ff 0d<br />
4d 27 90 7e 0f 85 fd fe ff ff e8 ea 53 8d ff e9 f3 fe ff ff 0b 01<br />
d2 44 89 d1 29 d1 ba 00 00 00 00 0f 48 ca e9 28 ff ff ff<br />
RSP: 0018:ffffc900002b0d08 EFLAGS: 00010297<br />
RAX: 0000000000000000 RBX: ffff888102398c80 RCX: 0000000080190009<br />
RDX: 0000000000000000 RSI: 000000000000006a RDI: 0000000000000000<br />
RBP: ffff888102398c00 R08: 0000000000000000 R09: 0000000000000000<br />
R10: 00000000000000ca R11: 0000000000015681 R12: 0000000000000001<br />
R13: ffffc900002b0d68 R14: ffff88811115e000 R15: ffff8881107aca40<br />
FS: 00007f41ded69500(0000) GS:ffff888667dc0000(0000)<br />
knlGS:0000000000000000<br />
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
CR2: 0000556ccc2dc1a0 CR3: 0000000104fd8003 CR4: 0000000000772ef0<br />
PKRU: 55555554<br />
Call Trace:<br />
<br />
? die+0x32/0x80<br />
? do_trap+0xd9/0x100<br />
? dql_completed+0x26b/0x290<br />
? dql_completed+0x26b/0x290<br />
? do_error_trap+0x6d/0xb0<br />
? dql_completed+0x26b/0x290<br />
? exc_invalid_op+0x4c/0x60<br />
? dql_completed+0x26b/0x290<br />
? asm_exc_invalid_op+0x16/0x20<br />
? dql_completed+0x26b/0x290<br />
__free_old_xmit+0xff/0x170 [virtio_net]<br />
free_old_xmit+0x54/0xc0 [virtio_net]<br />
virtnet_poll+0xf4/0xe30 [virtio_net]<br />
? __update_load_avg_cfs_rq+0x264/0x2d0<br />
? update_curr+0x35/0x260<br />
? reweight_entity+0x1be/0x260<br />
__napi_poll.constprop.0+0x28/0x1c0<br />
net_rx_action+0x329/0x420<br />
? enqueue_hrtimer+0x35/0x90<br />
? trace_hardirqs_on+0x1d/0x80<br />
? kvm_sched_clock_read+0xd/0x20<br />
? sched_clock+0xc/0x30<br />
? kvm_sched_clock_read+0xd/0x20<br />
? sched_clock+0xc/0x30<br />
? sched_clock_cpu+0xd/0x1a0<br />
handle_softirqs+0x138/0x3e0<br />
do_softirq.part.0+0x89/0xc0<br />
<br />
<br />
__local_bh_enable_ip+0xa7/0xb0<br />
virtnet_open+0xc8/0x310 [virtio_net]<br />
__dev_open+0xfa/0x1b0<br />
__dev_change_flags+0x1de/0x250<br />
dev_change_flags+0x22/0x60<br />
do_setlink.isra.0+0x2df/0x10b0<br />
? rtnetlink_rcv_msg+0x34f/0x3f0<br />
? netlink_rcv_skb+0x54/0x100<br />
? netlink_unicas<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
06/01/2025