CVE-2022-49346 - Understanding and Exploiting the Linux Kernel Refcount Leak in `gswip_gphy_fw_list`
On *December 16, 2022*, a vulnerability labeled CVE-2022-49346 was disclosed, affecting certain Linux kernel versions that utilize the Lantiq GSWIP (Gigabit Switch IP) driver. The flaw revolves around a *reference count leak* present in the gswip_gphy_fw_list function. If left unchecked, this bug can creep into critical systems, potentially leading to resource exhaustion, kernel panics, or exploitation scenarios.
Let’s break down what went wrong, how it was fixed, and how attackers or defenders can understand exploitation opportunities. We’ll use clear language, some code snippets, and links to official resources.
The Problem: Reference Count Leak
The code responsible for this bug lies in the DSA (Distributed Switch Architecture) driver for the Lantiq GSWIP chipsets (net/dsa/lantiq_gswip.c). Specifically, the problem source is the improper management of *device tree node* reference counts with the function of_node_put().
Technical Explanation
In Linux, device tree nodes (used to describe hardware components and their relationships) use a reference count mechanism. This means every time you get a reference to a node, you must "put" it back (release it with of_node_put()) when finished. Failure to do so results in a *memory leak*, keeping resources alive longer than they should be.
The following code is simplified for clarity
struct device_node *gphy_fw_np;
for_each_available_child_of_node(np, gphy_fw_np) {
if (wrong_node(gphy_fw_np))
break;
// do something
}
Notice: When the loop breaks early, the last node reference (gphy_fw_np) is not released.
Why is This a Problem?
According to the Linux device tree guidelines, every acquired device node reference must be freed.
If you fail to call of_node_put(), the kernel will think the node is still in use, even after you're done with it. Over time, repeated errors like this can cause the kernel to run out of resources, potentially leading to a denial of service.
The Fix
The patch that resolves this issue is simple and directly targets the leak by releasing the node on early exit.
for_each_available_child_of_node(np, gphy_fw_np) {
if (wrong_node(gphy_fw_np)) {
- break;
+ of_node_put(gphy_fw_np);
+ break;
}
}
For every early exit (like break), you add of_node_put(gphy_fw_np);.
See the official commit
- net: dsa: lantiq_gswip: Fix refcount leak in gswip_gphy_fw_list
What Could an Attacker Do?
While this bug is not a straightforward memory corruption or privilege escalation, reference count leaks can have serious impacts:
- Resource Exhaustion: An attacker might repeatedly trigger code paths that leak references, eventually causing the kernel to run out of node references or enter instability.
- Denial of Service: If reference leaks accumulate, the kernel may panic, refuse to load devices, or lock up due to missing resources.
- (Indirectly) Aid Other Exploits: Unreleased nodes might keep hardware or drivers alive, possibly interfering with device removal or preparation for other attacks.
How to Trigger the Leak
To exploit this bug, an attacker would typically need access to *device-tree-editing privileges* and be able to *load or reload drivers*:
> Exploit Scenario:
> 1. Prepare a device tree node structure that would make wrong_node() true on the first or early loop iteration.
> 2. Repeatedly load the affected Lantiq GSWIP driver, triggering the early exit and dropping the references.
> 3. Continue until resource exhaustion or undesired kernel behavior occurs.
Example Proof-of-Concept (Pseudo-code)
// This is not a real kernel exploit, but an illustration.
while (true) {
// force driver reload or node access
// ensure wrong_node() will trigger
// (could be achieved with a custom DT overlay, tools like devicetree compiler, or scripting sysfs reloads)
}
In Practice
- Exploitation is limited to those with root or kernel capabilities (e.g., custom firmware environments, test labs, or attackers with local escalation).
Quick Detect & Patch
Detection:
Use tools like kmemleak or static checkers (like Smatch) to detect leaked references on affected kernels.
Patch:
Upgrade your kernel to a version including or newer than this patch
Or, backport the one-liner fix above.
References
- CVE-2022-49346 at NVD
- Linux kernel patch commit
- Linux Device Tree Usage Documentation
- for_each_available_child_of_node() docs
Conclusion
CVE-2022-49346 shows how small coding slip-ups in kernel driver code can have lasting effects. Even though this bug is not a direct privilege escalation, reference count leaks are dangerous in the long run—especially in embedded or high-availability scenarios.
Upgrading or patching your systems is essential, and a good reminder to always *put back* what you *get*, especially with Linux kernel resource references.
Stay safe!
If you enjoyed this, or need personalized guidance, drop a comment!
Timeline
Published on: 02/26/2025 07:01:11 UTC
Last modified on: 05/04/2025 08:35:46 UTC