Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netrom: fix double-free in nr_route_frame()

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>

authored by

Jeongjun Park and committed by
Jakub Kicinski
ba1096c3 cdf8de9c

+9 -4
+9 -4
net/netrom/nr_route.c
··· 752 752 unsigned char *dptr; 753 753 ax25_cb *ax25s; 754 754 int ret; 755 - struct sk_buff *skbn; 755 + struct sk_buff *nskb, *oskb; 756 756 757 757 /* 758 758 * Reject malformed packets early. Check that it contains at least 2 ··· 811 811 /* We are going to change the netrom headers so we should get our 812 812 own skb, we also did not know until now how much header space 813 813 we had to reserve... - RXQ */ 814 - if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) { 814 + nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC); 815 + 816 + if (!nskb) { 815 817 nr_node_unlock(nr_node); 816 818 nr_node_put(nr_node); 817 819 dev_put(dev); 818 820 return 0; 819 821 } 820 - kfree_skb(skb); 821 - skb=skbn; 822 + oskb = skb; 823 + skb = nskb; 822 824 skb->data[14]--; 823 825 824 826 dptr = skb_push(skb, 1); ··· 838 836 ret = (nr_neigh->ax25 != NULL); 839 837 nr_node_unlock(nr_node); 840 838 nr_node_put(nr_node); 839 + 840 + if (ret) 841 + kfree_skb(oskb); 841 842 842 843 return ret; 843 844 }