CVE-2025-40003
Fecha de publicación:
18/10/2025
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: mscc: ocelot: Fix use-after-free caused by cyclic delayed work<br />
<br />
The origin code calls cancel_delayed_work() in ocelot_stats_deinit()<br />
to cancel the cyclic delayed work item ocelot->stats_work. However,<br />
cancel_delayed_work() may fail to cancel the work item if it is already<br />
executing. While destroy_workqueue() does wait for all pending work items<br />
in the work queue to complete before destroying the work queue, it cannot<br />
prevent the delayed work item from being rescheduled within the<br />
ocelot_check_stats_work() function. This limitation exists because the<br />
delayed work item is only enqueued into the work queue after its timer<br />
expires. Before the timer expiration, destroy_workqueue() has no visibility<br />
of this pending work item. Once the work queue appears empty,<br />
destroy_workqueue() proceeds with destruction. When the timer eventually<br />
expires, the delayed work item gets queued again, leading to the following<br />
warning:<br />
<br />
workqueue: cannot queue ocelot_check_stats_work on wq ocelot-switch-stats<br />
WARNING: CPU: 2 PID: 0 at kernel/workqueue.c:2255 __queue_work+0x875/0xaf0<br />
...<br />
RIP: 0010:__queue_work+0x875/0xaf0<br />
...<br />
RSP: 0018:ffff88806d108b10 EFLAGS: 00010086<br />
RAX: 0000000000000000 RBX: 0000000000000101 RCX: 0000000000000027<br />
RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffff88806d123e88<br />
RBP: ffffffff813c3170 R08: 0000000000000000 R09: ffffed100da247d2<br />
R10: ffffed100da247d1 R11: ffff88806d123e8b R12: ffff88800c00f000<br />
R13: ffff88800d7285c0 R14: ffff88806d0a5580 R15: ffff88800d7285a0<br />
FS: 0000000000000000(0000) GS:ffff8880e5725000(0000) knlGS:0000000000000000<br />
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
CR2: 00007fe18e45ea10 CR3: 0000000005e6c000 CR4: 00000000000006f0<br />
Call Trace:<br />
<br />
? kasan_report+0xc6/0xf0<br />
? __pfx_delayed_work_timer_fn+0x10/0x10<br />
? __pfx_delayed_work_timer_fn+0x10/0x10<br />
call_timer_fn+0x25/0x1c0<br />
__run_timer_base.part.0+0x3be/0x8c0<br />
? __pfx_delayed_work_timer_fn+0x10/0x10<br />
? rcu_sched_clock_irq+0xb06/0x27d0<br />
? __pfx___run_timer_base.part.0+0x10/0x10<br />
? try_to_wake_up+0xb15/0x1960<br />
? _raw_spin_lock_irq+0x80/0xe0<br />
? __pfx__raw_spin_lock_irq+0x10/0x10<br />
tmigr_handle_remote_up+0x603/0x7e0<br />
? __pfx_tmigr_handle_remote_up+0x10/0x10<br />
? sched_balance_trigger+0x1c0/0x9f0<br />
? sched_tick+0x221/0x5a0<br />
? _raw_spin_lock_irq+0x80/0xe0<br />
? __pfx__raw_spin_lock_irq+0x10/0x10<br />
? tick_nohz_handler+0x339/0x440<br />
? __pfx_tmigr_handle_remote_up+0x10/0x10<br />
__walk_groups.isra.0+0x42/0x150<br />
tmigr_handle_remote+0x1f4/0x2e0<br />
? __pfx_tmigr_handle_remote+0x10/0x10<br />
? ktime_get+0x60/0x140<br />
? lapic_next_event+0x11/0x20<br />
? clockevents_program_event+0x1d4/0x2a0<br />
? hrtimer_interrupt+0x322/0x780<br />
handle_softirqs+0x16a/0x550<br />
irq_exit_rcu+0xaf/0xe0<br />
sysvec_apic_timer_interrupt+0x70/0x80<br />
<br />
...<br />
<br />
The following diagram reveals the cause of the above warning:<br />
<br />
CPU 0 (remove) | CPU 1 (delayed work callback)<br />
mscc_ocelot_remove() |<br />
ocelot_deinit() | ocelot_check_stats_work()<br />
ocelot_stats_deinit() |<br />
cancel_delayed_work()| ...<br />
| queue_delayed_work()<br />
destroy_workqueue() | (wait a time)<br />
| __queue_work() //UAF<br />
<br />
The above scenario actually constitutes a UAF vulnerability.<br />
<br />
The ocelot_stats_deinit() is only invoked when initialization<br />
failure or resource destruction, so we must ensure that any<br />
delayed work items cannot be rescheduled.<br />
<br />
Replace cancel_delayed_work() with disable_delayed_work_sync()<br />
to guarantee proper cancellation of the delayed work item and<br />
ensure completion of any currently executing work before the<br />
workqueue is deallocated.<br />
<br />
A deadlock concern was considered: ocelot_stats_deinit() is called<br />
in a process context and is not holding any locks that the delayed<br />
work item might also need. Therefore, the use of the _sync() variant<br />
is safe here.<br />
<br />
This bug was identified through static analysis. To reproduce the<br />
issue and validate the fix, I simulated ocelot-swit<br />
---truncated---
Gravedad: Pendiente de análisis
Última modificación:
18/10/2025