CVE-2026-45989
Description
In the Linux kernel, the following vulnerability has been resolved:
of: unittest: fix use-after-free in testdrv_probe()
The function testdrv_probe() retrieves the device_node from the PCI device, applies an overlay, and then immediately calls of_node_put(dn). This releases the reference held by the PCI core, potentially freeing the node if the reference count drops to zero. Later, the same freed pointer 'dn' is passed to of_platform_default_populate(), leading to a use-after-free.
The reference to pdev->dev.of_node is owned by the device model and should not be released by the driver. Remove the erroneous of_node_put() to prevent premature freeing.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A use-after-free in the Linux kernel's of: unittest driver occurs when testdrv_probe() prematurely releases a device node reference, risking memory corruption.
Vulnerability
In the Linux kernel's of: unittest driver, the function testdrv_probe() retrieves the device node (dn) from a PCI device, applies an overlay, and then calls of_node_put(dn). This releases the reference held by the PCI core, potentially freeing the node if the reference count drops to zero. Later, the same freed pointer is passed to of_platform_default_populate(), leading to a use-after-free. The vulnerability affects versions of the Linux kernel prior to the inclusion of the fix commit [1].
Exploitation
An attacker would need the ability to trigger the testdrv_probe() code path, which typically requires local access and the ability to load or interact with the of: unittest driver. No special privileges beyond local user access are necessary if the driver is available. The sequence involves the driver probe function executing the overlay and then erroneously decrementing the device node reference count, causing the use-after-free when the freed node is later accessed.
Impact
Successful exploitation results in a use-after-free condition, which can lead to memory corruption. This may be leveraged for privilege escalation, denial of service (system crash), or potentially arbitrary code execution, depending on the kernel memory layout and attacker control.
Mitigation
The fix, as described in the kernel commit [1], removes the erroneous of_node_put() call from testdrv_probe(). The patch is included in the Linux kernel stable updates as of the publication date (2026-05-27). Users should apply the latest kernel updates from their distribution or directly cherry-pick the commit. No workaround is available other than avoiding the use of the of: unittest driver if the fix cannot be applied.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
10d68347b07b98of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index bd58b9524791e2..96d2e7b63db384 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4095,7 +4095,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
5b6122a67a29of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index f19abb42db40d6..02b780b6e8e254 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4202,7 +4202,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
6b2023286d2cof: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index eae7ebdf5130d9..4078569a0f9674 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4317,7 +4317,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
07fd339b2c25of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index eae7ebdf5130d9..4078569a0f9674 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4317,7 +4317,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
0ba03e06f037of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 4b7e663feee3d6..9af9d3f7418f1c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3862,7 +3862,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
0ba03e06f037of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 4b7e663feee3d6..9af9d3f7418f1c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3862,7 +3862,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
07fd339b2c25of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index eae7ebdf5130d9..4078569a0f9674 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4317,7 +4317,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
5b6122a67a29of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index f19abb42db40d6..02b780b6e8e254 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4202,7 +4202,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
d68347b07b98of: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index bd58b9524791e2..96d2e7b63db384 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4095,7 +4095,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
6b2023286d2cof: unittest: fix use-after-free in testdrv_probe()
1 file changed · +0 −2
drivers/of/unittest.c+0 −2 modifieddiff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index eae7ebdf5130d9..4078569a0f9674 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -4317,7 +4317,6 @@ static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) size = info->dtbo_end - info->dtbo_begin; ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); - of_node_put(dn); if (ret) return ret; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Premature reference count decrement (of_node_put) on a device_node pointer owned by the device model, causing a use-after-free when the freed pointer is later dereferenced."
Attack vector
An attacker capable of triggering the PCI driver probe path for the `pci_dt_testdrv` driver can cause a use-after-free. During `testdrv_probe()`, the driver calls `of_node_put(dn)` immediately after `of_overlay_fdt_apply()`, releasing the reference held by the PCI core. If the reference count drops to zero, the device_node is freed. The same freed pointer `dn` is then passed to `of_platform_default_populate()`, which dereferences the freed memory [patch_id=2660655]. No special network path or authentication is required beyond the ability to trigger the probe of this unittest PCI driver.
Affected code
The vulnerability is in the `testdrv_probe()` function within `drivers/of/unittest.c` [patch_id=2660655]. The function retrieves the `device_node` pointer `dn` from the PCI device (`pdev->dev.of_node`), applies an overlay via `of_overlay_fdt_apply()`, and then calls `of_node_put(dn)` before later passing `dn` to `of_platform_default_populate()`.
What the fix does
The patch removes the single line `of_node_put(dn);` from `testdrv_probe()` [patch_id=2660655]. The `device_node` pointer `dn` is obtained from `pdev->dev.of_node`, which is owned by the device model and should not be released by the driver. By removing the erroneous `of_node_put()`, the reference count is no longer prematurely decremented, preventing the node from being freed while it is still needed for the subsequent `of_platform_default_populate()` call.
Preconditions
- configThe kernel must be built with CONFIG_OF_UNITTEST and the pci_dt_testdrv driver must be present and probed.
- inputAn attacker must be able to trigger the probe of the pci_dt_testdrv PCI driver (e.g., via device enumeration or hotplug).
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/07fd339b2c253205794bea5d9b4b7548a4546c56nvd
- git.kernel.org/stable/c/0ba03e06f037df704d9b032e36d417633e2326bcnvd
- git.kernel.org/stable/c/5b6122a67a295f8a08b7c18d908a1bd974dfaec8nvd
- git.kernel.org/stable/c/6b2023286d2c6ed3bf964fb92e34c9c14d42eb69nvd
- git.kernel.org/stable/c/d68347b07b9801791c9eaab8f772770b52b8cd5cnvd
News mentions
0No linked articles in our index yet.