CVE-2024-43834 Information
Description
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:
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.
Reference
https://git.kernel.org/stable/c/3fc1be360b99baeea15cdee3cf94252cd3a72d26 https://git.kernel.org/stable/c/bf0ce5aa5f2525ed1b921ba36de96e458e77f482 https://git.kernel.org/stable/c/12144069209eec7f2090ce9afa15acdcc2c2a537 https://git.kernel.org/stable/c/59a931c5b732ca5fc2ca727f5a72aeabaafa85ec
Share on: