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

Configure Feed

Select the types of activity you want to include in your feed.

net: introduce skb_poison_list and use in kfree_skb_list

First user of skb_poison_list is in kfree_skb_list_reason, to catch bugs
earlier like introduced in commit eedade12f4cb ("net: kfree_skb_list use
kmem_cache_free_bulk"). For completeness mentioned bug have been fixed in
commit f72ff8b81ebc ("net: fix kfree_skb_list use of skb_mark_not_on_list").

In case of a bug like mentioned commit we would have seen OOPS with:
general protection fault, probably for non-canonical address 0xdead000000000870
And content of one the registers e.g. R13: dead000000000800

In this case skb->len is at offset 112 bytes (0x70) why fault happens at
0x800+0x70 = 0x870

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jesper Dangaard Brouer and committed by
David S. Miller
9dde0cd3 149e8fb0

+13 -1
+3
include/linux/poison.h
··· 81 81 /********** net/core/page_pool.c **********/ 82 82 #define PP_SIGNATURE (0x40 + POISON_POINTER_DELTA) 83 83 84 + /********** net/core/skbuff.c **********/ 85 + #define SKB_LIST_POISON_NEXT ((void *)(0x800 + POISON_POINTER_DELTA)) 86 + 84 87 /********** kernel/bpf/ **********/ 85 88 #define BPF_PTR_POISON ((void *)(0xeB9FUL + POISON_POINTER_DELTA)) 86 89
+7
include/linux/skbuff.h
··· 1738 1738 skb->next = NULL; 1739 1739 } 1740 1740 1741 + static inline void skb_poison_list(struct sk_buff *skb) 1742 + { 1743 + #ifdef CONFIG_DEBUG_NET 1744 + skb->next = SKB_LIST_POISON_NEXT; 1745 + #endif 1746 + } 1747 + 1741 1748 /* Iterate through singly-linked GSO fragments of an skb. */ 1742 1749 #define skb_list_walk_safe(first, skb, next_skb) \ 1743 1750 for ((skb) = (first), (next_skb) = (skb) ? (skb)->next : NULL; (skb); \
+3 -1
net/core/skbuff.c
··· 1000 1000 while (segs) { 1001 1001 struct sk_buff *next = segs->next; 1002 1002 1003 - if (__kfree_skb_reason(segs, reason)) 1003 + if (__kfree_skb_reason(segs, reason)) { 1004 + skb_poison_list(segs); 1004 1005 kfree_skb_add_bulk(segs, &sa, reason); 1006 + } 1005 1007 1006 1008 segs = next; 1007 1009 }