Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | // SPDX-License-Identifier: GPL-2.0 /* Converted from tools/testing/selftests/bpf/verifier/lwt.c */ #include <linux/bpf.h> #include <bpf/bpf_helpers.h> #include "bpf_misc.h" SEC("lwt_in") __description("invalid direct packet write for LWT_IN") __failure __msg("cannot write into packet") __naked void packet_write_for_lwt_in(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ *(u8*)(r2 + 0) = r2; \ l0_%=: 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("lwt_out") __description("invalid direct packet write for LWT_OUT") __failure __msg("cannot write into packet") __naked void packet_write_for_lwt_out(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ *(u8*)(r2 + 0) = r2; \ l0_%=: 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("lwt_xmit") __description("direct packet write for LWT_XMIT") __success __retval(0) __naked void packet_write_for_lwt_xmit(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ *(u8*)(r2 + 0) = r2; \ l0_%=: 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("lwt_in") __description("direct packet read for LWT_IN") __success __retval(0) __naked void packet_read_for_lwt_in(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ r0 = *(u8*)(r2 + 0); \ l0_%=: 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("lwt_out") __description("direct packet read for LWT_OUT") __success __retval(0) __naked void packet_read_for_lwt_out(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ r0 = *(u8*)(r2 + 0); \ l0_%=: 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("lwt_xmit") __description("direct packet read for LWT_XMIT") __success __retval(0) __naked void packet_read_for_lwt_xmit(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ r0 = *(u8*)(r2 + 0); \ l0_%=: 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("lwt_xmit") __description("overlapping checks for direct packet access") __success __retval(0) __naked void checks_for_direct_packet_access(void) { asm volatile (" \ r2 = *(u32*)(r1 + %[__sk_buff_data]); \ r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ r0 = r2; \ r0 += 8; \ if r0 > r3 goto l0_%=; \ r1 = r2; \ r1 += 6; \ if r1 > r3 goto l0_%=; \ r0 = *(u16*)(r2 + 6); \ l0_%=: 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("lwt_xmit") __description("make headroom for LWT_XMIT") __success __retval(0) __naked void make_headroom_for_lwt_xmit(void) { asm volatile (" \ r6 = r1; \ r2 = 34; \ r3 = 0; \ call %[bpf_skb_change_head]; \ /* split for s390 to succeed */ \ r1 = r6; \ r2 = 42; \ r3 = 0; \ call %[bpf_skb_change_head]; \ r0 = 0; \ exit; \ " : : __imm(bpf_skb_change_head) : __clobber_all); } SEC("socket") __description("invalid access of tc_classid for LWT_IN") __failure __msg("invalid bpf_context access") __failure_unpriv __naked void tc_classid_for_lwt_in(void) { asm volatile (" \ r0 = *(u32*)(r1 + %[__sk_buff_tc_classid]); \ exit; \ " : : __imm_const(__sk_buff_tc_classid, offsetof(struct __sk_buff, tc_classid)) : __clobber_all); } SEC("socket") __description("invalid access of tc_classid for LWT_OUT") __failure __msg("invalid bpf_context access") __failure_unpriv __naked void tc_classid_for_lwt_out(void) { asm volatile (" \ r0 = *(u32*)(r1 + %[__sk_buff_tc_classid]); \ exit; \ " : : __imm_const(__sk_buff_tc_classid, offsetof(struct __sk_buff, tc_classid)) : __clobber_all); } SEC("socket") __description("invalid access of tc_classid for LWT_XMIT") __failure __msg("invalid bpf_context access") __failure_unpriv __naked void tc_classid_for_lwt_xmit(void) { asm volatile (" \ r0 = *(u32*)(r1 + %[__sk_buff_tc_classid]); \ exit; \ " : : __imm_const(__sk_buff_tc_classid, offsetof(struct __sk_buff, tc_classid)) : __clobber_all); } SEC("lwt_in") __description("check skb->tc_classid half load not permitted for lwt prog") __failure __msg("invalid bpf_context access") __naked void not_permitted_for_lwt_prog(void) { asm volatile ( "r0 = 0;" #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ "r0 = *(u16*)(r1 + %[__sk_buff_tc_classid]);" #else "r0 = *(u16*)(r1 + %[__imm_0]);" #endif "exit;" : : __imm_const(__imm_0, offsetof(struct __sk_buff, tc_classid) + 2), __imm_const(__sk_buff_tc_classid, offsetof(struct __sk_buff, tc_classid)) : __clobber_all); } char _license[] SEC("license") = "GPL"; |