CVE-2024-46765 Information
Description
In the Linux kernel the following vulnerability has been resolved:
ice: protect XDP configuration with a mutex
The main threat to data consistency in ice_xdp() is a possible asynchronous PF reset. It can be triggered by a user or by TX timeout handler.
XDP setup and PF reset code access the same resources in the following sections: ice_vsi_close() in ice_prepare_for_reset() - already rtnl-locked ice_vsi_rebuild() for the PF VSI - not protected ice_vsi_open() - already rtnl-locked
With an unfortunate timing such accesses can result in a crash such as the one below:
[ +1.999878] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 14
[ +2.002992] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 18
[Mar15 18:17] ice 0000:b1:00.0 ens801f0np0: NETDEV WATCHDOG: CPU: 38: transmit queue 14 timed out 80692736 ms
[ +0.000093] ice 0000:b1:00.0 ens801f0np0: tx_timeout: VSI_num: 6 Q 14 NTC: 0x0 HW_HEAD: 0x0 NTU: 0x0 INT: 0x4000001
[ +0.000012] ice 0000:b1:00.0 ens801f0np0: tx_timeout recovery level 1 txqueue 14
[ +0.394718] ice 0000:b1:00.0: PTP reset successful
[ +0.006184] BUG: kernel NULL pointer dereference address: 0000000000000098
[ +0.000045] PF: supervisor read access in kernel mode
[ +0.000023] PF: error_code(0x0000) - not-present page
[ +0.000023] PGD 0 P4D 0
[ +0.000018] Oops: 0000 [1] PREEMPT SMP NOPTI
[ +0.000023] CPU: 38 PID: 7540 Comm: kworker/38:1 Not tainted 6.8.0-rc7 1
[ +0.000031] Hardware name: Intel Corporation S2600WFT/S2600WFT BIOS SE5C620.86B.02.01.0014.082620210524 08/26/2021
[ +0.000036] Workqueue: ice ice_service_task [ice]
[ +0.000183] RIP: 0010:ice_clean_tx_ring+0xa/0xd0 [ice]
[…]
[ +0.000013] Call Trace:
[ +0.000016]
The previous way of handling this through returning -EBUSY is not viable particularly when destroying AF_XDP socket because the kernel proceeds with removal anyway.
There is plenty of code between those calls and there is no need to create a large critical section that covers all of them same as there is no need to protect ice_vsi_rebuild() with rtnl_lock().
Add xdp_state_lock mutex to protect ice_vsi_rebuild() and ice_xdp().
Leaving unprotected sections in between would result in two states that have to be considered:
- when the VSI is closed but not yet rebuild
- when VSI is already rebuild but not yet open
The latter case is actually already handled through !netif_running() case we just need to adjust flag checking a little. The former one is not as trivial because between ice_vsi_close() and ice_vsi_rebuild() a lot of hardware interaction happens this can make adding/deleting rings exit with an error. Luckily VSI rebuild is pending and can apply new configuration for us in a managed fashion.
Therefore add an additional VSI state flag ICE_VSI_REBUILD_PENDING to indicate that ice_x
truncated—
Reference
https://git.kernel.org/stable/c/2f057db2fb29bc209c103050647562e60554d3d3 https://git.kernel.org/stable/c/391f7dae3d836891fc6cfbde38add2d0e10c6b7f https://git.kernel.org/stable/c/2504b8405768a57a71e660dbfd5abd59f679a03f
Share on: