CVE-2022-48868

Severity CVSS v4.0:
Pending analysis
Type:
CWE-476 NULL Pointer Dereference
Publication date:
21/08/2024
Last modified:
04/09/2024

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> dmaengine: idxd: Let probe fail when workqueue cannot be enabled<br /> <br /> The workqueue is enabled when the appropriate driver is loaded and<br /> disabled when the driver is removed. When the driver is removed it<br /> assumes that the workqueue was enabled successfully and proceeds to<br /> free allocations made during workqueue enabling.<br /> <br /> Failure during workqueue enabling does not prevent the driver from<br /> being loaded. This is because the error path within drv_enable_wq()<br /> returns success unless a second failure is encountered<br /> during the error path. By returning success it is possible to load<br /> the driver even if the workqueue cannot be enabled and<br /> allocations that do not exist are attempted to be freed during<br /> driver remove.<br /> <br /> Some examples of problematic flows:<br /> (a)<br /> <br /> idxd_dmaengine_drv_probe() -&gt; drv_enable_wq() -&gt; idxd_wq_request_irq():<br /> In above flow, if idxd_wq_request_irq() fails then<br /> idxd_wq_unmap_portal() is called on error exit path, but<br /> drv_enable_wq() returns 0 because idxd_wq_disable() succeeds. The<br /> driver is thus loaded successfully.<br /> <br /> idxd_dmaengine_drv_remove()-&gt;drv_disable_wq()-&gt;idxd_wq_unmap_portal()<br /> Above flow on driver unload triggers the WARN in devm_iounmap() because<br /> the device resource has already been removed during error path of<br /> drv_enable_wq().<br /> <br /> (b)<br /> <br /> idxd_dmaengine_drv_probe() -&gt; drv_enable_wq() -&gt; idxd_wq_request_irq():<br /> In above flow, if idxd_wq_request_irq() fails then<br /> idxd_wq_init_percpu_ref() is never called to initialize the percpu<br /> counter, yet the driver loads successfully because drv_enable_wq()<br /> returns 0.<br /> <br /> idxd_dmaengine_drv_remove()-&gt;__idxd_wq_quiesce()-&gt;percpu_ref_kill():<br /> Above flow on driver unload triggers a BUG when attempting to drop the<br /> initial ref of the uninitialized percpu ref:<br /> BUG: kernel NULL pointer dereference, address: 0000000000000010<br /> <br /> Fix the drv_enable_wq() error path by returning the original error that<br /> indicates failure of workqueue enabling. This ensures that the probe<br /> fails when an error is encountered and the driver remove paths are only<br /> attempted when the workqueue was enabled successfully.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.15 (including) 5.15.90 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.1.8 (excluding)