History

selftests/bpf: Add test for stale pkt range after scalar arithmetic

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

Daniel Borkmann committed 7 months ago

Commit 8697bdd1 parent 9f118091 file · +61 −0Browse files

Unified · Split

tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c+61−0
@@ -859,4 +859,65 @@ l0_%=: r0 = 1; \ · 858 unmodified lines
859 : __clobber_all);859 : __clobber_all);
860}860}
861 861
862SEC("tc")
863__description("direct packet access: pkt_range cleared after sub with known scalar")
864__failure __msg("invalid access to packet")
865__naked void pkt_range_clear_after_sub(void)
866{
867 asm volatile (" \
868 r9 = *(u32*)(r1 + %[__sk_buff_data]); \
869 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \
870 r9 += 256; \
871 if r9 >= r8 goto l0_%=; \
872 r0 = 0; \
873 exit; \
874l0_%=: /* r9 has AT_PKT_END (pkt + 256 >= pkt_end) */ \
875 r9 -= 256; \
876 /* \
877 * AT_PKT_END must not survive the arithmetic. \
878 * is_pkt_ptr_branch_taken must validate both \
879 * branches when visiting the next condition. \
880 */ \
881 if r9 < r8 goto l1_%=; \
882 r0 = 0; \
883 exit; \
884l1_%=: r0 = *(u8*)(r9 + 0); \
885 r0 = 0; \
886 exit; \
887" :
888 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
889 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
890 : __clobber_all);
891}
892
893SEC("tc")
894__description("direct packet access: pkt_range cleared after add with known scalar")
895__failure __msg("invalid access to packet")
896__naked void pkt_range_clear_after_add(void)
897{
898 asm volatile (" \
899 r9 = *(u32*)(r1 + %[__sk_buff_data]); \
900 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \
901 r9 += 256; \
902 if r9 >= r8 goto l0_%=; \
903 r0 = 0; \
904 exit; \
905l0_%=: /* r9 has AT_PKT_END (pkt + 256 >= pkt_end) */ \
906 r9 += -256; \
907 /* \
908 * Same as sub, but goes through BPF_ADD path. \
909 * AT_PKT_END must not survive the arithmetic. \
910 */ \
911 if r9 < r8 goto l1_%=; \
912 r0 = 0; \
913 exit; \
914l1_%=: r0 = *(u8*)(r9 + 0); \
915 r0 = 0; \
916 exit; \
917" :
918 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
919 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
920 : __clobber_all);
921}
922
862char _license[] SEC("license") = "GPL";923char _license[] SEC("license") = "GPL";