Nick Zavaritsky reported [0] a bug in verifier, where the following unsafe program is not rejected: __attribute__((__noinline__)) long skb_pull_data(struct __sk_buff *sk, __u32 len) { return bpf_skb_pull_data(sk, len); } SEC("tc") int test_invalidate_checks(struct __sk_buff *sk) { int *p = (void *)(long)sk->data; if ((void *)(p + 1) > (void *)(long)sk->data_end) return TCX_DROP; skb_pull_data(sk, 0); /* not safe, p is invalid after bpf_skb_pull_data call */ *p = 42; return TCX_PASS; } This happens because verifier does not track package invalidation effect of global sub-programs. This patch-set fixes the issue by modifying check_cfg() to compute whether or not each sub-program calls (directly or indirectly) helper invalidating packet pointers. [0] https://lore.kernel.org/bpf/0498CA22-5779-4767-9C0C-A9515CEA711F@xxxxxxxxx/ Eduard Zingerman (4): bpf: add find_containing_subprog() utility function bpf: refactor bpf_helper_changes_pkt_data to use helper number bpf: track changes_pkt_data property for global functions selftests/bpf: test for changing packet data from global functions include/linux/bpf_verifier.h | 1 + include/linux/filter.h | 2 +- kernel/bpf/core.c | 2 +- kernel/bpf/verifier.c | 62 ++++++++++++++++-- net/core/filter.c | 63 +++++++++---------- .../selftests/bpf/progs/verifier_sock.c | 28 +++++++++ 6 files changed, 115 insertions(+), 43 deletions(-) -- 2.47.0