netrom: fix double-free in nr_route_frame()

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: 1da177e4c3 ("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>
Signed-off-by: Ulrich Hecht <uli@kernel.org>
This commit is contained in:
Jeongjun Park authored and Ulrich Hecht committed 2026-02-20 13:22:32 +08:00
1 parent c3f6696234
commit 97cfda023b
1 file changed
+9 -4
+9 -4
View File
@@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
unsigned char *dptr; unsigned char *dptr;
ax25_cb *ax25s; ax25_cb *ax25s;
int ret; int ret;
struct sk_buff *skbn; struct sk_buff *nskb, *oskb;
/* /*
* Reject malformed packets early. Check that it contains at least 2 * 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 /* 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 own skb, we also did not know until now how much header space
we had to reserve... - RXQ */ 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_unlock(nr_node);
nr_node_put(nr_node); nr_node_put(nr_node);
dev_put(dev); dev_put(dev);
return 0; return 0;
} }
kfree_skb(skb); oskb = skb;
skb=skbn; skb = nskb;
skb->data[14]--; skb->data[14]--;
dptr = skb_push(skb, 1); 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_unlock(nr_node);
nr_node_put(nr_node); nr_node_put(nr_node);
if (ret)
kfree_skb(oskb);
return ret; return ret;
} }