VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45925

CVE-2026-45925

Description

In the Linux kernel, the following vulnerability has been resolved:

thermal/of: Fix reference leak in thermal_of_cm_lookup()

In thermal_of_cm_lookup(), tr_np is obtained via of_parse_phandle(), but never released.

Use the __free(device_node) cleanup attribute to automatically release the node and fix the leak.

[ rjw: Changelog edits ]

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A reference leak in Linux kernel's thermal_of_cm_lookup() due to missing of_node_put() on tr_np can cause resource exhaustion.

Vulnerability

The Linux kernel's thermal subsystem contains a reference leak in the thermal_of_cm_lookup() function. The function obtains a device node pointer tr_np via of_parse_phandle(), which increments the reference count of the node, but never releases it with of_node_put(). This bug affects all kernel versions that include the commit introducing this code path; the fix is applied in the stable tree as commit a1fe789a96fe (referenced in [1]).

Exploitation

An attacker does not need any special privileges or network access, because the vulnerability is triggered by normal thermal zone registration during system boot or device enumeration. Any system that uses device tree-based thermal management will hit the code path in thermal_of_cm_lookup(). The missing release causes a slow, cumulative reference count increment each time the function is called, eventually leading to exhaustion of device node references.

Impact

Successful exploitation results in resource exhaustion (memory leak and inability to release device nodes), which can cause degraded system performance and eventually lead to denial of service (system instability or hang) due to kernel memory starvation. No confidentiality or integrity impact is expected.

Mitigation

The fix was incorporated into the Linux kernel stable tree as commit a1fe789a96fe47733c133134fd264cb7ca832395 [1]. Users should apply the latest stable kernel updates that include this commit. As a workaround, systems not using device tree-based thermal management are not affected. The vulnerability is not known to be listed on CISA's KEV.

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

1

Patches

8
a1fe789a96fe

thermal/of: Fix reference leak in thermal_of_cm_lookup()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFelix GuJan 23, 2026Fixed in 7.0via kernel-cna
1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
025796ccd7f9

thermal/of: Fix reference leak in thermal_of_cm_lookup()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFelix GuJan 23, 2026Fixed in 6.19.4via kernel-cna
1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
8af710156c53

thermal/of: Fix reference leak in thermal_of_cm_lookup()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFelix GuJan 23, 2026Fixed in 6.12.75via kernel-cna
1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index e0aa9d9d5604b7..3e674f2d66316e 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -299,10 +299,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
8344d5da9df7

thermal/of: Fix reference leak in thermal_of_cm_lookup()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFelix GuJan 23, 2026Fixed in 6.18.14via kernel-cna
1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
8af710156c53

thermal/of: Fix reference leak in thermal_of_cm_lookup()

1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index e0aa9d9d5604b7..3e674f2d66316e 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -299,10 +299,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
a1fe789a96fe

thermal/of: Fix reference leak in thermal_of_cm_lookup()

1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
025796ccd7f9

thermal/of: Fix reference leak in thermal_of_cm_lookup()

1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    
8344d5da9df7

thermal/of: Fix reference leak in thermal_of_cm_lookup()

1 file changed · +2 3
  • drivers/thermal/thermal_of.c+2 3 modified
    diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
    index 1a51a4d240ff60..b6d0c92f5522bd 100644
    --- a/drivers/thermal/thermal_of.c
    +++ b/drivers/thermal/thermal_of.c
    @@ -280,10 +280,10 @@ static bool thermal_of_cm_lookup(struct device_node *cm_np,
     				 struct cooling_spec *c)
     {
     	for_each_child_of_node_scoped(cm_np, child) {
    -		struct device_node *tr_np;
     		int count, i;
     
    -		tr_np = of_parse_phandle(child, "trip", 0);
    +		struct device_node *tr_np __free(device_node) =
    +			of_parse_phandle(child, "trip", 0);
     		if (tr_np != trip->priv)
     			continue;
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing `of_node_put()` call after `of_parse_phandle()` in `thermal_of_cm_lookup()` causes a device-node reference leak."

Attack vector

An attacker who can trigger thermal device-tree parsing (e.g., by loading a thermal zone or cooling device) causes `thermal_of_cm_lookup()` to be called. Each call obtains a `struct device_node` via `of_parse_phandle()` without releasing it, leaking a reference to the kernel's device node reference count. Over repeated invocations this exhausts the reference counter, preventing the node from being freed and potentially leading to resource exhaustion or denial of service. No special privileges are required beyond the ability to trigger thermal binding lookups.

Affected code

The vulnerability is in the `thermal_of_cm_lookup()` function in `drivers/thermal/thermal_of.c` [patch_id=2661272]. The function obtains a device node reference via `of_parse_phandle(child, "trip", 0)` but never releases it, causing a reference leak on every call.

What the fix does

The patch replaces the bare `struct device_node *tr_np` declaration with `struct device_node *tr_np __free(device_node)`, which uses the Linux kernel's automatic cleanup attribute. When `tr_np` goes out of scope (at the end of each `for_each_child_of_node_scoped` iteration), the `__free(device_node)` attribute automatically calls `of_node_put()` to release the reference obtained by `of_parse_phandle()`. This closes the leak without adding explicit `of_node_put()` calls.

Preconditions

  • configThe system must have device-tree thermal zones with cooling maps that reference trip points via the 'trip' phandle property.
  • inputAn attacker must be able to trigger thermal binding lookups, e.g., by loading/unloading thermal drivers or triggering thermal zone re-evaluation.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.