selftests/bpf: test for changing packet data from global functions

commit 3f23ee5590d9605dbde9a5e1d4b97637a4803329 upstream.

Check if verifier is aware of packet pointers invalidation done in
global functions. Based on a test shared by Nick Zavaritsky in [0].

[0] https://lore.kernel.org/bpf/0498CA22-5779-4767-9C0C-A9515CEA711F@gmail.com/

Suggested-by: Nick Zavaritsky <mejedi@gmail.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20241210041100.1898468-5-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Eduard Zingerman
2025-04-30 16:19:46 +08:00
committed by Greg Kroah-Hartman
parent 79751e9227
commit 85a30a4639

View File

@@ -977,4 +977,32 @@ l1_%=: r0 = *(u8*)(r7 + 0); \
: __clobber_all);
}
__noinline
long skb_pull_data2(struct __sk_buff *sk, __u32 len)
{
return bpf_skb_pull_data(sk, len);
}
__noinline
long skb_pull_data1(struct __sk_buff *sk, __u32 len)
{
return skb_pull_data2(sk, len);
}
/* global function calls bpf_skb_pull_data(), which invalidates packet
* pointers established before global function call.
*/
SEC("tc")
__failure __msg("invalid mem access")
int invalidate_pkt_pointers_from_global_func(struct __sk_buff *sk)
{
int *p = (void *)(long)sk->data;
if ((void *)(p + 1) > (void *)(long)sk->data_end)
return TCX_DROP;
skb_pull_data1(sk, 0);
*p = 42; /* this is unsafe */
return TCX_PASS;
}
char _license[] SEC("license") = "GPL";