cve/2024/CVE-2024-56674.md
2025-09-29 16:08:36 +00:00

4.3 KiB

CVE-2024-56674

Description

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

POC

Reference

No PoCs from references.

Github