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.

Merge branch 'net-fix-potential-crash-in-net-sched-cls_u32-c'

Eric Dumazet says:

====================
net: fix potential crash in net/sched/cls_u32.c

GangMin Kim provided a report and a repro fooling u32_classify().

Add skb_header_pointer_careful() variant of skb_header_pointer()
and use it in net/sched/cls_u32.c.

Later we can also use it in net/sched/act_pedit.c
====================

Link: https://patch.msgid.link/20260128141539.3404400-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+18 -7
+12
include/linux/skbuff.h
··· 4301 4301 skb_headlen(skb), buffer); 4302 4302 } 4303 4303 4304 + /* Variant of skb_header_pointer() where @offset is user-controlled 4305 + * and potentially negative. 4306 + */ 4307 + static inline void * __must_check 4308 + skb_header_pointer_careful(const struct sk_buff *skb, int offset, 4309 + int len, void *buffer) 4310 + { 4311 + if (unlikely(offset < 0 && -offset > skb_headroom(skb))) 4312 + return NULL; 4313 + return skb_header_pointer(skb, offset, len, buffer); 4314 + } 4315 + 4304 4316 static inline void * __must_check 4305 4317 skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len) 4306 4318 {
+6 -7
net/sched/cls_u32.c
··· 161 161 int toff = off + key->off + (off2 & key->offmask); 162 162 __be32 *data, hdata; 163 163 164 - if (skb_headroom(skb) + toff > INT_MAX) 165 - goto out; 166 - 167 - data = skb_header_pointer(skb, toff, 4, &hdata); 164 + data = skb_header_pointer_careful(skb, toff, 4, 165 + &hdata); 168 166 if (!data) 169 167 goto out; 170 168 if ((*data ^ key->val) & key->mask) { ··· 212 214 if (ht->divisor) { 213 215 __be32 *data, hdata; 214 216 215 - data = skb_header_pointer(skb, off + n->sel.hoff, 4, 216 - &hdata); 217 + data = skb_header_pointer_careful(skb, 218 + off + n->sel.hoff, 219 + 4, &hdata); 217 220 if (!data) 218 221 goto out; 219 222 sel = ht->divisor & u32_hash_fold(*data, &n->sel, ··· 228 229 if (n->sel.flags & TC_U32_VAROFFSET) { 229 230 __be16 *data, hdata; 230 231 231 - data = skb_header_pointer(skb, 232 + data = skb_header_pointer_careful(skb, 232 233 off + n->sel.offoff, 233 234 2, &hdata); 234 235 if (!data)