CVE-2026-46219
Description
In the Linux kernel, the following vulnerability has been resolved:
spi: mpc52xx: fix use-after-free on unbind
The state machine work is scheduled by the interrupt handler and therefore needs to be cancelled after disabling interrupts to avoid a potential use-after-free.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Use-after-free in mpc52xx SPI driver on Linux kernel during device unbind.
Vulnerability
The mpc52xx SPI driver in the Linux kernel contains a use-after-free vulnerability that occurs during device unbind. The state machine work is scheduled by the interrupt handler but is not cancelled after disabling interrupts, leading to a race condition where the work may execute after the device resources have been freed. This affects the SPI subsystem of the PowerPC mpc52xx platform. The affected versions include those prior to the commit 6c3e413919a1 [1].
Exploitation
An attacker with the ability to trigger a device unbind (e.g., through hotplug removal or driver unbind) can exploit this race. The vulnerability requires that interrupts are still active when the unbind starts, allowing the workqueue to be scheduled. Successful exploitation may involve precise timing to hit the race window between resource release and work execution. The attack requires local access and the ability to remove the SPI device.
Impact
A successful exploit causes a use-after-free condition, which can lead to a denial of service (system crash) or potential privilege escalation if the freed memory is reallocated and controlled by the attacker. The impact is confined to the kernel context, potentially allowing an attacker to corrupt kernel memory.
Mitigation
This vulnerability is fixed by commit 6c3e413919a12627d04a31a4a5fccb9fc129bb02 in the Linux kernel [1]. Systems should update to a kernel version containing this fix or apply the patch. No workaround is available. The fix ensures that the state machine work is cancelled after disabling interrupts, preventing the race condition.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
10706b3dc2ac7aspi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 823b49f8ece2a2..c8c8e6bdf421dd 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -519,10 +519,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
ee52da0dd83espi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index ad01dd1ad0b38b..a4991f3bc9b63e 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -525,10 +525,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
6c3e413919a1spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index a8d3cecb276b23..84aade14160685 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -525,10 +525,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
bbcd6dd8e9f2spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 157228562d65d8..924d820448fb4a 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -522,10 +522,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
bb6b50f709c5spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index b8e2d9263fc88d..16ab333af00903 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -519,10 +519,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) struct mpc52xx_spi *ms = spi_master_get_devdata(master); int i; - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
bb6b50f709c5spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index b8e2d9263fc88d..16ab333af00903 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -519,10 +519,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) struct mpc52xx_spi *ms = spi_master_get_devdata(master); int i; - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
6c3e413919a1spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index a8d3cecb276b23..84aade14160685 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -525,10 +525,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
706b3dc2ac7aspi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 823b49f8ece2a2..c8c8e6bdf421dd 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -519,10 +519,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
bbcd6dd8e9f2spi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 157228562d65d8..924d820448fb4a 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -522,10 +522,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
ee52da0dd83espi: mpc52xx: fix use-after-free on unbind
1 file changed · +2 −2
drivers/spi/spi-mpc52xx.c+2 −2 modifieddiff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index ad01dd1ad0b38b..a4991f3bc9b63e 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -525,10 +525,11 @@ static void mpc52xx_spi_remove(struct platform_device *op) spi_unregister_controller(host); - cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); + cancel_work_sync(&ms->work); + for (i = 0; i < ms->gpio_cs_count; i++) gpiod_put(ms->gpio_cs[i]); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Incorrect ordering in the remove path: work queue cancellation was performed before disabling interrupts, allowing a racing interrupt to reschedule the work after cancellation and cause a use-after-free."
Attack vector
An attacker with the ability to trigger driver unbinding (e.g., via hotplug removal or module unloading) can cause a use-after-free. During unbind, the old code cancelled the work queue item before freeing the IRQs. Because the interrupt handler can schedule the state machine work, a racing interrupt arriving after `cancel_work_sync()` but before `free_irq()` could reschedule the work, which would then execute on freed driver data after the remove function continues.
Affected code
The vulnerability is in the `mpc52xx_spi_remove()` function in `drivers/spi/spi-mpc52xx.c`. The original code called `cancel_work_sync(&ms->work)` before `free_irq()`, leaving a window where an interrupt could reschedule the work after it was cancelled but before the interrupt handler was freed.
What the fix does
The patch moves `cancel_work_sync(&ms->work)` to after both `free_irq(ms->irq0, ms)` and `free_irq(ms->irq1, ms)` calls. This ensures that interrupts are fully disabled before the work item is cancelled, closing the race window where an interrupt handler could reschedule the work after it was already cancelled but before the IRQ was freed. The fix is minimal — a two-line reorder in the remove function.
Preconditions
- inputThe attacker must be able to trigger unbind of the mpc52xx SPI driver (e.g., via device removal or module unloading).
- inputA racing interrupt must fire between cancel_work_sync and free_irq in the original code path.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/6c3e413919a12627d04a31a4a5fccb9fc129bb02nvd
- git.kernel.org/stable/c/706b3dc2ac7a998c55e14b3fd2e8f934c367e6e0nvd
- git.kernel.org/stable/c/bb6b50f709c5a01906ff72a07fdc070bb3357188nvd
- git.kernel.org/stable/c/bbcd6dd8e9f264440eaf6167382bf404911c1c46nvd
- git.kernel.org/stable/c/ee52da0dd83ebcd89ecbbe2660c57b15a25489f2nvd
News mentions
0No linked articles in our index yet.