mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
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>
This commit is contained in:
commit
de5720f91b
|
|
@ -4301,6 +4301,18 @@ skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer)
|
|||
skb_headlen(skb), buffer);
|
||||
}
|
||||
|
||||
/* Variant of skb_header_pointer() where @offset is user-controlled
|
||||
* and potentially negative.
|
||||
*/
|
||||
static inline void * __must_check
|
||||
skb_header_pointer_careful(const struct sk_buff *skb, int offset,
|
||||
int len, void *buffer)
|
||||
{
|
||||
if (unlikely(offset < 0 && -offset > skb_headroom(skb)))
|
||||
return NULL;
|
||||
return skb_header_pointer(skb, offset, len, buffer);
|
||||
}
|
||||
|
||||
static inline void * __must_check
|
||||
skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -161,10 +161,8 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
|||
int toff = off + key->off + (off2 & key->offmask);
|
||||
__be32 *data, hdata;
|
||||
|
||||
if (skb_headroom(skb) + toff > INT_MAX)
|
||||
goto out;
|
||||
|
||||
data = skb_header_pointer(skb, toff, 4, &hdata);
|
||||
data = skb_header_pointer_careful(skb, toff, 4,
|
||||
&hdata);
|
||||
if (!data)
|
||||
goto out;
|
||||
if ((*data ^ key->val) & key->mask) {
|
||||
|
|
@ -214,8 +212,9 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
|||
if (ht->divisor) {
|
||||
__be32 *data, hdata;
|
||||
|
||||
data = skb_header_pointer(skb, off + n->sel.hoff, 4,
|
||||
&hdata);
|
||||
data = skb_header_pointer_careful(skb,
|
||||
off + n->sel.hoff,
|
||||
4, &hdata);
|
||||
if (!data)
|
||||
goto out;
|
||||
sel = ht->divisor & u32_hash_fold(*data, &n->sel,
|
||||
|
|
@ -229,7 +228,7 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
|||
if (n->sel.flags & TC_U32_VAROFFSET) {
|
||||
__be16 *data, hdata;
|
||||
|
||||
data = skb_header_pointer(skb,
|
||||
data = skb_header_pointer_careful(skb,
|
||||
off + n->sel.offoff,
|
||||
2, &hdata);
|
||||
if (!data)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user