UBUNTU-CVE-2024-43834
In the Linux kernel, the following vulnerability has been resolved: xdp: fix invalid wait context of page_pool_destroy() If the driver uses a page pool, it creates a page pool with page_pool_create(). The reference count of page pool is 1 as default. A page pool will be destroyed only when a reference count reaches 0. page_pool_destroy() is used to destroy page pool, it decreases a reference count. When a page pool is destroyed, ->disconnect() is called, which is mem_allocator_disconnect(). This function internally acquires mutex_lock(). If the driver uses XDP, it registers a memory model with xdp_rxq_info_reg_mem_model(). The xdp_rxq_info_reg_mem_model() internally increases a page pool reference count if a memory model is a page pool. Now the reference count is 2. To destroy a page pool, the driver should call both page_pool_destroy() and xdp_unreg_mem_model(). The xdp_unreg_mem_model() internally calls page_pool_destroy(). Only page_pool_destroy() decreases a reference count. If a driver calls page_pool_destroy() then xdp_unreg_mem_model(), we will face an invalid wait context warning. Because xdp_unreg_mem_model() calls page_pool_destroy() with rcu_read_lock(). The page_pool_destroy() internally acquires mutex_lock(). Splat looks like: ============================= [ BUG: Invalid wait context ] 6.10.0-rc6+ #4 Tainted: G W ----------------------------- ethtool/1806 is trying to lock: ffffffff90387b90 (mem_id_lock){+.+.}-{4:4}, at: mem_allocator_disconnect+0x73/0x150 other info that might help us debug this: context-{5:5} 3 locks held by ethtool/1806: stack backtrace: CPU: 0 PID: 1806 Comm: ethtool Tainted: G W 6.10.0-rc6+ #4 f916f41f172891c800f2fed Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021 Call Trace: <TASK> dump_stack_lvl+0x7e/0xc0 __lock_acquire+0x1681/0x4de0 ? _printk+0x64/0xe0 ? __pfx_mark_lock.part.0+0x10/0x10 ? __pfx___lock_acquire+0x10/0x10 lock_acquire+0x1b3/0x580 ? mem_allocator_disconnect+0x73/0x150 ? __wake_up_klogd.part.0+0x16/0xc0 ? __pfx_lock_acquire+0x10/0x10 ? dump_stack_lvl+0x91/0xc0 __mutex_lock+0x15c/0x1690 ? mem_allocator_disconnect+0x73/0x150 ? __pfx_prb_read_valid+0x10/0x10 ? mem_allocator_disconnect+0x73/0x150 ? __pfx_llist_add_batch+0x10/0x10 ? console_unlock+0x193/0x1b0 ? lockdep_hardirqs_on+0xbe/0x140 ? __pfx___mutex_lock+0x10/0x10 ? tick_nohz_tick_stopped+0x16/0x90 ? __irq_work_queue_local+0x1e5/0x330 ? irq_work_queue+0x39/0x50 ? __wake_up_klogd.part.0+0x79/0xc0 ? mem_allocator_disconnect+0x73/0x150 mem_allocator_disconnect+0x73/0x150 ? __pfx_mem_allocator_disconnect+0x10/0x10 ? mark_held_locks+0xa5/0xf0 ? rcu_is_watching+0x11/0xb0 page_pool_release+0x36e/0x6d0 page_pool_destroy+0xd7/0x440 xdp_unreg_mem_model+0x1a7/0x2a0 ? __pfx_xdp_unreg_mem_model+0x10/0x10 ? kfree+0x125/0x370 ? bnxt_free_ring.isra.0+0x2eb/0x500 ? bnxt_free_mem+0x5ac/0x2500 xdp_rxq_info_unreg+0x4a/0xd0 bnxt_free_mem+0x1356/0x2500 bnxt_close_nic+0xf0/0x3b0 ? __pfx_bnxt_close_nic+0x10/0x10 ? ethnl_parse_bit+0x2c6/0x6d0 ? __pfx___nla_validate_parse+0x10/0x10 ? __pfx_ethnl_parse_bit+0x10/0x10 bnxt_set_features+0x2a8/0x3e0 __netdev_update_features+0x4dc/0x1370 ? ethnl_parse_bitset+0x4ff/0x750 ? __pfx_ethnl_parse_bitset+0x10/0x10 ? __pfx___netdev_update_features+0x10/0x10 ? mark_held_locks+0xa5/0xf0 ? _raw_spin_unlock_irqrestore+0x42/0x70 ? __pm_runtime_resume+0x7d/0x110 ethnl_set_features+0x32d/0xa20 To fix this problem, it uses rhashtable_lookup_fast() instead of rhashtable_lookup() with rcu_read_lock(). Using xa without rcu_read_lock() here is safe. xa is freed by __xdp_mem_allocator_rcu_free() and this is called by call_rcu() of mem_xa_remove(). The mem_xa_remove() is called by page_pool_destroy() if a reference count reaches 0. The xa is already protected by the reference count mechanism well in the control plane. So removing rcu_read_lock() for page_pool_destroy() is safe.
02 / AFFECTED SOFTWARE
Affected packages
116 explicit affected versions
120 explicit affected versions
76 explicit affected versions
33 explicit affected versions
1 explicit affected versions
121 explicit affected versions
1 explicit affected versions
10 explicit affected versions
8 explicit affected versions
7 explicit affected versions
50 explicit affected versions
10 explicit affected versions
14 explicit affected versions
28 explicit affected versions
4 explicit affected versions
1 explicit affected versions
1 explicit affected versions
11 explicit affected versions
53 explicit affected versions
38 explicit affected versions
52 explicit affected versions
50 explicit affected versions
6 explicit affected versions
14 explicit affected versions
12 explicit affected versions
19 explicit affected versions
6 explicit affected versions
61 explicit affected versions
47 explicit affected versions
91 explicit affected versions
57 explicit affected versions
47 explicit affected versions
10 explicit affected versions
8 explicit affected versions
14 explicit affected versions
54 explicit affected versions
7 explicit affected versions
14 explicit affected versions
53 explicit affected versions
9 explicit affected versions
13 explicit affected versions
11 explicit affected versions
35 explicit affected versions
21 explicit affected versions
14 explicit affected versions
18 explicit affected versions
18 explicit affected versions
15 explicit affected versions
64 explicit affected versions
16 explicit affected versions
10 explicit affected versions
13 explicit affected versions
4 explicit affected versions
23 explicit affected versions
18 explicit affected versions
124 explicit affected versions
16 explicit affected versions
7 explicit affected versions
12 explicit affected versions
45 explicit affected versions
12 explicit affected versions
14 explicit affected versions
7 explicit affected versions
104 explicit affected versions
12 explicit affected versions
7 explicit affected versions
10 explicit affected versions
105 explicit affected versions
12 explicit affected versions
9 explicit affected versions
14 explicit affected versions
9 explicit affected versions
1 explicit affected versions
10 explicit affected versions
37 explicit affected versions
13 explicit affected versions
26 explicit affected versions
13 explicit affected versions
9 explicit affected versions
29 explicit affected versions
111 explicit affected versions
13 explicit affected versions
58 explicit affected versions
8 explicit affected versions
9 explicit affected versions
100 explicit affected versions
56 explicit affected versions
18 explicit affected versions
33 explicit affected versions
23 explicit affected versions
10 explicit affected versions
1 explicit affected versions
11 explicit affected versions
12 explicit affected versions
7 explicit affected versions
12 explicit affected versions
45 explicit affected versions
39 explicit affected versions
78 explicit affected versions
55 explicit affected versions
10 explicit affected versions
26 explicit affected versions
16 explicit affected versions
16 explicit affected versions
1 explicit affected versions
7 explicit affected versions
17 explicit affected versions
13 explicit affected versions
16 explicit affected versions
58 explicit affected versions
17 explicit affected versions
46 explicit affected versions
3 explicit affected versions
132 explicit affected versions
1 explicit affected versions
2 explicit affected versions
51 explicit affected versions
14 explicit affected versions
12 explicit affected versions
44 explicit affected versions
27 explicit affected versions
30 explicit affected versions
19 explicit affected versions
5 explicit affected versions
8 explicit affected versions
1 explicit affected versions
10 explicit affected versions
13 explicit affected versions
13 explicit affected versions
110 explicit affected versions
13 explicit affected versions
72 explicit affected versions
12 explicit affected versions
108 explicit affected versions
80 explicit affected versions
56 explicit affected versions
44 explicit affected versions
16 explicit affected versions
3 explicit affected versions
13 explicit affected versions
26 explicit affected versions
44 explicit affected versions
37 explicit affected versions
17 explicit affected versions
14 explicit affected versions
38 explicit affected versions
47 explicit affected versions
9 explicit affected versions
47 explicit affected versions
11 explicit affected versions
8 explicit affected versions
7 explicit affected versions
55 explicit affected versions
7 explicit affected versions
53 explicit affected versions
13 explicit affected versions
43 explicit affected versions
77 explicit affected versions
119 explicit affected versions
10 explicit affected versions
8 explicit affected versions
12 explicit affected versions
88 explicit affected versions
14 explicit affected versions
4 explicit affected versions
78 explicit affected versions
11 explicit affected versions
1 explicit affected versions
123 explicit affected versions
10 explicit affected versions
03 / CONNECTIONS
Connected vulnerabilities
04 / EVIDENCE
Source records
In the Linux kernel, the following vulnerability has been resolved: xdp: fix invalid wait context of page_pool_destroy() If the driver uses a page pool, it creates a page pool with page_pool_create(). The reference count of page pool is 1 as default. A page pool will be destroyed only when a reference count reaches 0. page_pool_destroy() is used to destroy page pool, it decreases a reference count. When a page pool is destroyed, ->disconnect() is called, which is mem_allocator_disconnect(). This function internally acquires mutex_lock(). If the driver uses XDP, it registers a memory model with xdp_rxq_info_reg_mem_model(). The xdp_rxq_info_reg_mem_model() internally increases a page pool reference count if a memory model is a page pool. Now the reference count is 2. To destroy a page pool, the driver should call both page_pool_destroy() and xdp_unreg_mem_model(). The xdp_unreg_mem_model() internally calls page_pool_destroy(). Only page_pool_destroy() decreases a reference count. If a driver calls page_pool_destroy() then xdp_unreg_mem_model(), we will face an invalid wait context warning. Because xdp_unreg_mem_model() calls page_pool_destroy() with rcu_read_lock(). The page_pool_destroy() internally acquires mutex_lock(). Splat looks like: ============================= [ BUG: Invalid wait context ] 6.10.0-rc6+ #4 Tainted: G W ----------------------------- ethtool/1806 is trying to lock: ffffffff90387b90 (mem_id_lock){+.+.}-{4:4}, at: mem_allocator_disconnect+0x73/0x150 other info that might help us debug this: context-{5:5} 3 locks held by ethtool/1806: stack backtrace: CPU: 0 PID: 1806 Comm: ethtool Tainted: G W 6.10.0-rc6+ #4 f916f41f172891c800f2fed Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021 Call Trace: <TASK> dump_stack_lvl+0x7e/0xc0 __lock_acquire+0x1681/0x4de0 ? _printk+0x64/0xe0 ? __pfx_mark_lock.part.0+0x10/0x10 ? __pfx___lock_acquire+0x10/0x10 lock_acquire+0x1b3/0x580 ? mem_allocator_disconnect+0x73/0x150 ? __wake_up_klogd.part.0+0x16/0xc0 ? __pfx_lock_acquire+0x10/0x10 ? dump_stack_lvl+0x91/0xc0 __mutex_lock+0x15c/0x1690 ? mem_allocator_disconnect+0x73/0x150 ? __pfx_prb_read_valid+0x10/0x10 ? mem_allocator_disconnect+0x73/0x150 ? __pfx_llist_add_batch+0x10/0x10 ? console_unlock+0x193/0x1b0 ? lockdep_hardirqs_on+0xbe/0x140 ? __pfx___mutex_lock+0x10/0x10 ? tick_nohz_tick_stopped+0x16/0x90 ? __irq_work_queue_local+0x1e5/0x330 ? irq_work_queue+0x39/0x50 ? __wake_up_klogd.part.0+0x79/0xc0 ? mem_allocator_disconnect+0x73/0x150 mem_allocator_disconnect+0x73/0x150 ? __pfx_mem_allocator_disconnect+0x10/0x10 ? mark_held_locks+0xa5/0xf0 ? rcu_is_watching+0x11/0xb0 page_pool_release+0x36e/0x6d0 page_pool_destroy+0xd7/0x440 xdp_unreg_mem_model+0x1a7/0x2a0 ? __pfx_xdp_unreg_mem_model+0x10/0x10 ? kfree+0x125/0x370 ? bnxt_free_ring.isra.0+0x2eb/0x500 ? bnxt_free_mem+0x5ac/0x2500 xdp_rxq_info_unreg+0x4a/0xd0 bnxt_free_mem+0x1356/0x2500 bnxt_close_nic+0xf0/0x3b0 ? __pfx_bnxt_close_nic+0x10/0x10 ? ethnl_parse_bit+0x2c6/0x6d0 ? __pfx___nla_validate_parse+0x10/0x10 ? __pfx_ethnl_parse_bit+0x10/0x10 bnxt_set_features+0x2a8/0x3e0 __netdev_update_features+0x4dc/0x1370 ? ethnl_parse_bitset+0x4ff/0x750 ? __pfx_ethnl_parse_bitset+0x10/0x10 ? __pfx___netdev_update_features+0x10/0x10 ? mark_held_locks+0xa5/0xf0 ? _raw_spin_unlock_irqrestore+0x42/0x70 ? __pm_runtime_resume+0x7d/0x110 ethnl_set_features+0x32d/0xa20 To fix this problem, it uses rhashtable_lookup_fast() instead of rhashtable_lookup() with rcu_read_lock(). Using xa without rcu_read_lock() here is safe. xa is freed by __xdp_mem_allocator_rcu_free() and this is called by call_rcu() of mem_xa_remove(). The mem_xa_remove() is called by page_pool_destroy() if a reference count reaches 0. The xa is already protected by the reference count mechanism well in the control plane. So removing rcu_read_lock() for page_pool_destroy() is safe.
05 / REFERENCES
Further evidence
- https://git.kernel.org/linus/59a931c5b732ca5fc2ca727f5a72aeabaafa85ec
- https://git.kernel.org/stable/c/12144069209eec7f2090ce9afa15acdcc2c2a537
- https://git.kernel.org/stable/c/3fc1be360b99baeea15cdee3cf94252cd3a72d26
- https://git.kernel.org/stable/c/59a931c5b732ca5fc2ca727f5a72aeabaafa85ec
- https://git.kernel.org/stable/c/6c390ef198aa69795427a5cb5fd7cb4bc7e6cd7a
- https://git.kernel.org/stable/c/be9d08ff102df3ac4f66e826ea935cf3af63a4bd
- https://git.kernel.org/stable/c/bf0ce5aa5f2525ed1b921ba36de96e458e77f482
- https://ubuntu.com/security/CVE-2024-43834
- https://ubuntu.com/security/notices/USN-7100-1
- https://ubuntu.com/security/notices/USN-7100-2
- https://ubuntu.com/security/notices/USN-7123-1
- https://ubuntu.com/security/notices/USN-7144-1
- https://ubuntu.com/security/notices/USN-7154-1
- https://ubuntu.com/security/notices/USN-7154-2
- https://ubuntu.com/security/notices/USN-7155-1
- https://ubuntu.com/security/notices/USN-7156-1
- https://ubuntu.com/security/notices/USN-7194-1
- https://ubuntu.com/security/notices/USN-7196-1
- https://www.cve.org/CVERecord?id=CVE-2024-43834