In the Linux kernel, the following vulnerability has been resolved:
media: cx23885: cancel NetUP CI work before teardown
netup_ci_exit() frees a netup_ci_state while its work item,
netup_read_ci_status(), may still be pending or running on the system
workqueue. The worker obtains the state with container_of() and
dereferences it, so it must not outlive the state.
netup_ci_init() queues the initial status read, and CI GPIO interrupts
subsequently queue the same work from netup_ci_slot_status(). During
remove, cx23885_finidev() calls free_irq() before the CI device is
unregistered. free_irq() prevents further IRQ handlers from running,
but does not drain work queued previously, so the worker can run after
netup_ci_exit() frees the state.
Call cancel_work_sync() before dvb_ca_en50221_release() and kfree().
This issue was found by an in-house static analysis tool.
CVSS Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7.8
AV:L - The use-after-free is reached only on local PCI teardown of the NetUP Dual DVB-S2 CI card (cx23885_finidev → cx23885_dvb_unregister → netup_ci_exit) via sysfs unbind/remove, rmmod, or local PCI hot-remove. No network, adjacent-network, or remote-peer path queues netup_read_ci_status or frees netup_ci_state.
AC:L - netup_ci_init() unconditionally schedule_work()s the status worker, and CAM GPIO IRQs re-queue it via netup_ci_slot_status(); an attacker who then unbinds/rebinds controls both sides of the missing cancel_work_sync race. The worker's 33-byte I2C transfer widens a retryable window, so this UAF is Low complexity.
PR:L - Per CNA driver-removal UAF precedent on this same NetUP PCIe DVB family (CVE-2023-53219), an unprivileged local video-group/uaccess user on broadcast, HTPC, or set-top systems can spray the freed netup_ci_state while teardown proceeds. Init-namespace root is not required for the UAF itself.
UI:N - The attacker queues the CI work (driver bind or CAM GPIO) and initiates PCI unbind, rmmod, or hot-remove themselves. No separate victim action such as mounting a filesystem or opening attacker-supplied content is required.
S:U - The use-after-free corrupts the host kernel netup_ci_state heap object and dvb_ca_en50221 private state within the same security authority. It is not a VM escape, IOMMU/DMA isolation bypass, or sandbox breakout.
C:H - After kfree(state), netup_read_ci_status recovers the object via container_of() and reads state->ca, i2c_adap, and status from freed memory. Spraying the slab turns this kernel heap UAF into an arbitrary read, which per UAF guidance is Confidentiality High.
I:H - The dangling worker writes state->status/next_status_checked_time and calls dvb_ca_en50221_frda_irq(), which loads ca->pub->read_cam_control from the freed object, a heap-spray function-pointer hijack. UAF memory corruption is scored Integrity High.
A:H - Use-after-free of netup_ci_state from workqueue context after kfree, or a NULL deref of ca->private if the worker interleaves dvb_ca_en50221_release, oopses or panics the kernel even when not fully exploited, so availability impact is High.
| Attack Vector |
Local |
Scope |
Unchanged |
| Attack Complexity |
Low |
Confidentiality Impact |
High |
| Privileges Required |
Low |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:L - The use-after-free is reached only on local PCI teardown of the NetUP Dual DVB-S2 CI card (cx23885_finidev → cx23885_dvb_unregister → netup_ci_exit) via sysfs unbind/remove, rmmod, or local PCI hot-remove. No network, adjacent-network, or remote-peer path queues netup_read_ci_status or frees netup_ci_state.
AC:L - netup_ci_init() unconditionally schedule_work()s the status worker, and CAM GPIO IRQs re-queue it via netup_ci_slot_status(); an attacker who then unbinds/rebinds controls both sides of the missing cancel_work_sync race. The worker's 33-byte I2C transfer widens a retryable window, so this UAF is Low complexity.
PR:L - Per CNA driver-removal UAF precedent on this same NetUP PCIe DVB family (CVE-2023-53219), an unprivileged local video-group/uaccess user on broadcast, HTPC, or set-top systems can spray the freed netup_ci_state while teardown proceeds. Init-namespace root is not required for the UAF itself.
UI:N - The attacker queues the CI work (driver bind or CAM GPIO) and initiates PCI unbind, rmmod, or hot-remove themselves. No separate victim action such as mounting a filesystem or opening attacker-supplied content is required.
S:U - The use-after-free corrupts the host kernel netup_ci_state heap object and dvb_ca_en50221 private state within the same security authority. It is not a VM escape, IOMMU/DMA isolation bypass, or sandbox breakout.
C:H - After kfree(state), netup_read_ci_status recovers the object via container_of() and reads state->ca, i2c_adap, and status from freed memory. Spraying the slab turns this kernel heap UAF into an arbitrary read, which per UAF guidance is Confidentiality High.
I:H - The dangling worker writes state->status/next_status_checked_time and calls dvb_ca_en50221_frda_irq(), which loads ca->pub->read_cam_control from the freed object, a heap-spray function-pointer hijack. UAF memory corruption is scored Integrity High.
A:H - Use-after-free of netup_ci_state from workqueue context after kfree, or a NULL deref of ca->private if the worker interleaves dvb_ca_en50221_release, oopses or panics the kernel even when not fully exploited, so availability impact is High.
CVSS 3.1