]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netrom: fix double-free in nr_route_frame()
authorJeongjun Park <aha310510@gmail.com>
Mon, 19 Jan 2026 06:33:59 +0000 (15:33 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 30 Jan 2026 09:27:40 +0000 (10:27 +0100)
commit ba1096c315283ee3292765f6aea4cca15816c4f7 upstream.

In nr_route_frame(), old_skb is immediately freed without checking if
nr_neigh->ax25 pointer is NULL. Therefore, if nr_neigh->ax25 is NULL,
the caller function will free old_skb again, causing a double-free bug.

Therefore, to prevent this, we need to modify it to check whether
nr_neigh->ax25 is NULL before freeing old_skb.

Cc: <stable@vger.kernel.org>
Reported-by: syzbot+999115c3bf275797dc27@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69694d6f.050a0220.58bed.0029.GAE@google.com/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Jeongjun Park <aha310510@gmail.com>
Link: https://patch.msgid.link/20260119063359.10604-1-aha310510@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netrom/nr_route.c

index 0b270893ee14c5a2f048e88df724b0ae23f70ffa..89e4bf4aa652096e9ca811a2d64a8be96a46ce37 100644 (file)
@@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        unsigned char *dptr;
        ax25_cb *ax25s;
        int ret;
-       struct sk_buff *skbn;
+       struct sk_buff *nskb, *oskb;
 
        /*
         * Reject malformed packets early. Check that it contains at least 2
@@ -811,14 +811,16 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        /* We are going to change the netrom headers so we should get our
           own skb, we also did not know until now how much header space
           we had to reserve... - RXQ */
-       if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
+       nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC);
+
+       if (!nskb) {
                nr_node_unlock(nr_node);
                nr_node_put(nr_node);
                dev_put(dev);
                return 0;
        }
-       kfree_skb(skb);
-       skb=skbn;
+       oskb = skb;
+       skb = nskb;
        skb->data[14]--;
 
        dptr  = skb_push(skb, 1);
@@ -837,6 +839,9 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        nr_node_unlock(nr_node);
        nr_node_put(nr_node);
 
+       if (ret)
+               kfree_skb(oskb);
+
        return ret;
 }