[PATCH OLK-6.6 0/2] bpf mainline
Daniel Borkmann (2): bpf: Drop pkt_end markers on arithmetic to prevent is_pkt_ptr_branch_taken selftests/bpf: Add test for stale pkt range after scalar arithmetic kernel/bpf/verifier.c | 22 +++++++ .../bpf/progs/verifier_direct_packet_access.c | 61 +++++++++++++++++++ 2 files changed, 83 insertions(+) -- 2.34.1
From: Daniel Borkmann <daniel@iogearbox.net> mainline inclusion from mainline-v7.1-rc1 commit 9f118095dd341885dbc3f1cd6a028414da099aba category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9180 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- When a pkt pointer acquires AT_PKT_END or BEYOND_PKT_END range from a comparison, and then, known-constant arithmetic is performed, adjust_ptr_min_max_vals() copies the stale range via dst_reg->raw = ptr_reg->raw without clearing the negative reg->range sentinel values. This lets is_pkt_ptr_branch_taken() choose one branch direction and skip going through the other. Fix this by clearing negative pkt range values (that is, AT_PKT_END and BEYOND_PKT_END) after arithmetic on pkt pointers. This ensures is_pkt_ptr_branch_taken() returns unknown and both branches are properly verified. Fixes: 6d94e741a8ff ("bpf: Support for pointers beyond pkt_end.") Reported-by: STAR Labs SG <info@starlabs.sg> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20260409155016.536608-1-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org> Conflicts: kernel/bpf/verifier.c [Not merged commit 022ac0750883] Signed-off-by: Pu Lehui <pulehui@huawei.com> --- kernel/bpf/verifier.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7ad363512643..d87251727192 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12881,6 +12881,17 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, dst_reg->var_off = ptr_reg->var_off; dst_reg->off = ptr_reg->off + smin_val; dst_reg->raw = ptr_reg->raw; + + if (reg_is_pkt_pointer(ptr_reg)) { + /* + * Clear range for unknown addends since we can't know + * where the pkt pointer ended up. Also clear AT_PKT_END / + * BEYOND_PKT_END from prior comparison as any pointer + * arithmetic invalidates them. + */ + if (dst_reg->range < 0) + memset(&dst_reg->raw, 0, sizeof(dst_reg->raw)); + } break; } /* A new variable offset is created. Note that off_reg->off @@ -12944,6 +12955,17 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, dst_reg->id = ptr_reg->id; dst_reg->off = ptr_reg->off - smin_val; dst_reg->raw = ptr_reg->raw; + + if (reg_is_pkt_pointer(ptr_reg)) { + /* + * Clear range for unknown addends since we can't know + * where the pkt pointer ended up. Also clear AT_PKT_END / + * BEYOND_PKT_END from prior comparison as any pointer + * arithmetic invalidates them. + */ + if (dst_reg->range < 0) + memset(&dst_reg->raw, 0, sizeof(dst_reg->raw)); + } break; } /* A new variable offset is created. If the subtrahend is known -- 2.34.1
From: Daniel Borkmann <daniel@iogearbox.net> mainline inclusion from mainline-v7.1-rc1 commit 8697bdd67be87fc007c1ea2f98a59e29ae902170 category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9180 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Extend the verifier_direct_packet_access BPF selftests to exercise the verifier code paths which ensure that the pkt range is cleared after add/sub alu with a known scalar. The tests reject the invalid access. # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_direct [...] #592/35 verifier_direct_packet_access/direct packet access: pkt_range cleared after sub with known scalar:OK #592/36 verifier_direct_packet_access/direct packet access: pkt_range cleared after add with known scalar:OK #592/37 verifier_direct_packet_access/direct packet access: test3:OK #592/38 verifier_direct_packet_access/direct packet access: test3 @unpriv:OK #592/39 verifier_direct_packet_access/direct packet access: test34 (non-linear, cgroup_skb/ingress, too short eth):OK #592/40 verifier_direct_packet_access/direct packet access: test35 (non-linear, cgroup_skb/ingress, too short 1):OK #592/41 verifier_direct_packet_access/direct packet access: test36 (non-linear, cgroup_skb/ingress, long enough):OK #592 verifier_direct_packet_access:OK [...] Summary: 2/47 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20260409155016.536608-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Pu Lehui <pulehui@huawei.com> --- .../bpf/progs/verifier_direct_packet_access.c | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c b/tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c index 99a23dea8233..bd9676cf9e16 100644 --- a/tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c +++ b/tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c @@ -800,4 +800,65 @@ l0_%=: /* exit(0) */ \ : __clobber_all); } +SEC("tc") +__description("direct packet access: pkt_range cleared after sub with known scalar") +__failure __msg("invalid access to packet") +__naked void pkt_range_clear_after_sub(void) +{ + asm volatile (" \ + r9 = *(u32*)(r1 + %[__sk_buff_data]); \ + r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ + r9 += 256; \ + if r9 >= r8 goto l0_%=; \ + r0 = 0; \ + exit; \ +l0_%=: /* r9 has AT_PKT_END (pkt + 256 >= pkt_end) */ \ + r9 -= 256; \ + /* \ + * AT_PKT_END must not survive the arithmetic. \ + * is_pkt_ptr_branch_taken must validate both \ + * branches when visiting the next condition. \ + */ \ + if r9 < r8 goto l1_%=; \ + r0 = 0; \ + exit; \ +l1_%=: r0 = *(u8*)(r9 + 0); \ + r0 = 0; \ + exit; \ +" : + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) + : __clobber_all); +} + +SEC("tc") +__description("direct packet access: pkt_range cleared after add with known scalar") +__failure __msg("invalid access to packet") +__naked void pkt_range_clear_after_add(void) +{ + asm volatile (" \ + r9 = *(u32*)(r1 + %[__sk_buff_data]); \ + r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ + r9 += 256; \ + if r9 >= r8 goto l0_%=; \ + r0 = 0; \ + exit; \ +l0_%=: /* r9 has AT_PKT_END (pkt + 256 >= pkt_end) */ \ + r9 += -256; \ + /* \ + * Same as sub, but goes through BPF_ADD path. \ + * AT_PKT_END must not survive the arithmetic. \ + */ \ + if r9 < r8 goto l1_%=; \ + r0 = 0; \ + exit; \ +l1_%=: r0 = *(u8*)(r9 + 0); \ + r0 = 0; \ + exit; \ +" : + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) + : __clobber_all); +} + char _license[] SEC("license") = "GPL"; -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/23383 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/TAX... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/23383 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/TAX...
participants (2)
-
patchwork bot -
Pu Lehui