]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: hsr: fix NULL pointer dereference in hsr_get_node_data()
authorQuan Sun <2022090917019@std.uestc.edu.cn>
Fri, 8 May 2026 12:46:36 +0000 (20:46 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 12 May 2026 10:28:34 +0000 (12:28 +0200)
In the HSR (High-availability Seamless Redundancy) protocol, node
information is maintained in the node_db. When a supervision frame is
received, node->addr_B_port is updated to track the receiving port type
(e.g., HSR_PT_SLAVE_B).

If the underlying physical interface associated with this slave port is
removed (e.g., via `ip link del`), hsr_del_port() frees the hsr_port
object. However, the stale node->addr_B_port reference is kept in the
node_db until the node ages out.

Subsequently, if userspace queries the node status via the Netlink
command HSR_C_GET_NODE_STATUS, the kernel calls hsr_get_node_data().
This function unconditionally dereferences the pointer returned by
hsr_port_get_hsr():

    if (node->addr_B_port != HSR_PT_NONE) {
            port = hsr_port_get_hsr(hsr, node->addr_B_port);
            *addr_b_ifindex = port->dev->ifindex; // <-- NULL deref
    }

If the slave port has been deleted, hsr_port_get_hsr() returns NULL,
resulting in a kernel panic.

Oops: general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:hsr_get_node_data+0x7b6/0x9e0
Call Trace:
 <TASK>
 hsr_get_node_status+0x445/0xa40

Fix this by adding a proper NULL pointer check. If the port lookup fails
due to a stale port type, gracefully treat it as if no valid port exists
and assign -1 to the interface index.

Steps to reproduce:
1. Create an HSR interface with two slave devices.
2. Receive a supervision frame to populate node_db with
   addr_B_port assigned to SLAVE_B.
3. Delete the underlying slave device B.
4. Send an HSR_C_GET_NODE_STATUS Netlink message.

Fixes: c5a759117210 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
Signed-off-by: Quan Sun <2022090917019@std.uestc.edu.cn>
Link: https://patch.msgid.link/20260508124636.1462346-1-2022090917019@std.uestc.edu.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/hsr/hsr_framereg.c

index d09875b335885e2553783cf4508b2171abce4efa..124619920d3863c743b5c6ded7fb218422696050 100644 (file)
@@ -889,7 +889,10 @@ int hsr_get_node_data(struct hsr_priv *hsr,
 
        if (node->addr_B_port != HSR_PT_NONE) {
                port = hsr_port_get_hsr(hsr, node->addr_B_port);
-               *addr_b_ifindex = port->dev->ifindex;
+               if (port)
+                       *addr_b_ifindex = port->dev->ifindex;
+               else
+                       *addr_b_ifindex = -1;
        } else {
                *addr_b_ifindex = -1;
        }