mirror of
https://github.com/torvalds/linux.git
synced 2026-09-27 19:42:03 +02:00
bpf: Fix bounds check for skb-backed dynptrs
The skb_pointer_if_linear() function checks whether a
memory region of length len starting at offset off into
the skb is in the linear area, and returns a pointer to
the region if so. The check currently subtracts between
skb_headlen and offset of the check, and since skb_headlen
is unsigned the subtraction can underflow. This causes the
bounds check to spuriously pass and generate an arbitrary
pointer of the form *(skb->data + off).
The only user of this helper is currently skb-backed BPF
dynptr code. Returning the wrong pointer leads to the
dynptr erroneously being backed with invalid memory.
Ensure the subtraction cannot underflow, and fail the check if
it would. Use u64 arithmetic to also prevent overflow when
calculating (skb_headlen(skb) - off) since off is unsigned.
Fixes: 6f5a630d7c ("bpf, net: Introduce skb_pointer_if_linear().")
Reported-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260922172028.6269-2-emil@etsalapatis.com
This commit is contained in:
parent
0b6e06f950
commit
ed6eec97b5
|
|
@ -4372,7 +4372,10 @@ skb_header_pointer_careful(const struct sk_buff *skb, int offset,
|
|||
static inline void * __must_check
|
||||
skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len)
|
||||
{
|
||||
if (likely(skb_headlen(skb) - offset >= len))
|
||||
unsigned int uoffset = (unsigned int)offset;
|
||||
|
||||
if (likely(uoffset <= skb_headlen(skb) &&
|
||||
(unsigned int)len <= skb_headlen(skb) - uoffset))
|
||||
return skb->data + offset;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user