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
Unified · Split
| @@ -859,4 +859,65 @@ l0_%=: r0 = 1; \ · 858 unmodified lines | ||
| 859 | 859 | : __clobber_all); |
| 860 | 860 | } |
| 861 | 861 | |
| 862 | +SEC("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; \ | |
| 874 | +l0_%=: /* 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; \ | |
| 884 | +l1_%=: 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 | + | |
| 893 | +SEC("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; \ | |
| 905 | +l0_%=: /* 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; \ | |
| 914 | +l1_%=: 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 | + | |
| 862 | 923 | char _license[] SEC("license") = "GPL"; |