CVE-2022-49351 is a vulnerability patched in the Linux kernel related to a reference count leak in the altera_tse_mdio_create function, which is part of the Altera TSE (Triple Speed Ethernet) network driver. In simple words, this bug could allow local users to cause a resource leak in the kernel, leading potentially to system instability or exploit conditions.

Let's break down what went wrong, how it can be abused, and how it was fixed. If you want deep technical but easy-to-read insight, keep scrolling.

What Exactly Is the Vulnerability?

In the Linux device tree handling code, there's a loop called for_each_child_of_node() used to walk through child nodes in the hardware description. Every time it moves to the next child node, the previous one gets released (reference count decreases). But if you break out of such a loop early, the current node reference isn't released—and that’s a memory reference leak.

In the case of altera_tse_mdio_create, this leak happened between the kernel’s Device Tree core and Altera's networking driver.

Here's the buggy part

struct device_node *child;

for_each_child_of_node(np, child) {
    if (something_fails(child)) {
        break;  // oops, leaked reference here!
    }
    // do stuff with child
}
// no explicit release of 'child' after break

What Are The Risks?

- Resource Exhaustion: Over time, running code that triggers this bug leaks system memory (specifically, references to device tree nodes). On embedded or long-running systems, this causes kernel memory to fill up, possibly crashing your device.
- Local Denial of Service: An attacker with local access could intentionally trigger this code path repeatedly to hog resources, leading to a system hang.

Exploiting the Leak: Proof-of-Concept

While this isn't an RCE or privilege escalation bug by itself, it's quite useful for local denial-of-service (DoS). For example, a custom program could repeatedly trigger altera_tse_mdio_create with a device tree setup that forces the function to break out of the loop early.

Exploit Concept

// Pseudo-code: set up device tree nodes to make 'something_fails(child)' true
while (1) {
    trigger_altera_tse_mdio_create();
    // Optionally monitor slab info for leaked nodes
}

*Note:* You'd need to patch the device tree or run code that can manipulate the networking subsystem, possibly requiring root privileges, but in embedded or VM scenarios, this is not impossible.

The Fix: Releasing the Reference

The fix is really simple: After breaking out of the loop, explicitly release the reference to the node.

Patch

struct device_node *child;

for_each_child_of_node(np, child) {
    if (something_fails(child)) {
        of_node_put(child); // <-- fix: release reference
        break;
    }
    // do stuff with child
}

Commit Reference:
- Linux kernel commit

Here is the original patch discussion on lore.kernel.org.

Key Takeaways

- Always pair every node acquisition with an explicit release, especially when you break loops with reference-counted objects.

More Info

- CVE Entry
- Upstream Linux Commit
- Linux for_each_child_of_node() documentation

Final Thoughts

If you are maintaining embedded devices, network equipment, or edge Linux systems, update your kernel ASAP if you use this driver. Even 'minor' leaks in the kernel can snowball into serious issues in production!

This CVE proves once again: even small mistakes with kernel references can have wide-reaching impact, and being attentive in coding and code review is critical.


*This post was made for security learners, embedded engineers, and sysadmins wanting not just to patch, but to understand what's really going on under the hood.*

Timeline

Published on: 02/26/2025 07:01:11 UTC
Last modified on: 04/14/2025 19:46:06 UTC