Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: verifier/direct_packet_access converted to inline assembly

Test verifier/direct_packet_access automatically converted to use inline assembly.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20230421174234.2391278-8-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
0a372c9c 60802802

+805 -710
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 20 20 #include "verifier_ctx.skel.h" 21 21 #include "verifier_ctx_sk_msg.skel.h" 22 22 #include "verifier_d_path.skel.h" 23 + #include "verifier_direct_packet_access.skel.h" 23 24 #include "verifier_direct_stack_access_wraparound.skel.h" 24 25 #include "verifier_div0.skel.h" 25 26 #include "verifier_div_overflow.skel.h" ··· 102 101 void test_verifier_ctx(void) { RUN(verifier_ctx); } 103 102 void test_verifier_ctx_sk_msg(void) { RUN(verifier_ctx_sk_msg); } 104 103 void test_verifier_d_path(void) { RUN(verifier_d_path); } 104 + void test_verifier_direct_packet_access(void) { RUN(verifier_direct_packet_access); } 105 105 void test_verifier_direct_stack_access_wraparound(void) { RUN(verifier_direct_stack_access_wraparound); } 106 106 void test_verifier_div0(void) { RUN(verifier_div0); } 107 107 void test_verifier_div_overflow(void) { RUN(verifier_div_overflow); }
+803
tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Converted from tools/testing/selftests/bpf/verifier/direct_packet_access.c */ 3 + 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include "bpf_misc.h" 7 + 8 + SEC("tc") 9 + __description("pkt_end - pkt_start is allowed") 10 + __success __retval(TEST_DATA_LEN) 11 + __naked void end_pkt_start_is_allowed(void) 12 + { 13 + asm volatile (" \ 14 + r0 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 15 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 16 + r0 -= r2; \ 17 + exit; \ 18 + " : 19 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 20 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 21 + : __clobber_all); 22 + } 23 + 24 + SEC("tc") 25 + __description("direct packet access: test1") 26 + __success __retval(0) 27 + __naked void direct_packet_access_test1(void) 28 + { 29 + asm volatile (" \ 30 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 31 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 32 + r0 = r2; \ 33 + r0 += 8; \ 34 + if r0 > r3 goto l0_%=; \ 35 + r0 = *(u8*)(r2 + 0); \ 36 + l0_%=: r0 = 0; \ 37 + exit; \ 38 + " : 39 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 40 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 41 + : __clobber_all); 42 + } 43 + 44 + SEC("tc") 45 + __description("direct packet access: test2") 46 + __success __retval(0) 47 + __naked void direct_packet_access_test2(void) 48 + { 49 + asm volatile (" \ 50 + r0 = 1; \ 51 + r4 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 52 + r3 = *(u32*)(r1 + %[__sk_buff_data]); \ 53 + r5 = r3; \ 54 + r5 += 14; \ 55 + if r5 > r4 goto l0_%=; \ 56 + r0 = *(u8*)(r3 + 7); \ 57 + r4 = *(u8*)(r3 + 12); \ 58 + r4 *= 14; \ 59 + r3 = *(u32*)(r1 + %[__sk_buff_data]); \ 60 + r3 += r4; \ 61 + r2 = *(u32*)(r1 + %[__sk_buff_len]); \ 62 + r2 <<= 49; \ 63 + r2 >>= 49; \ 64 + r3 += r2; \ 65 + r2 = r3; \ 66 + r2 += 8; \ 67 + r1 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 68 + if r2 > r1 goto l1_%=; \ 69 + r1 = *(u8*)(r3 + 4); \ 70 + l1_%=: r0 = 0; \ 71 + l0_%=: exit; \ 72 + " : 73 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 74 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)), 75 + __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 76 + : __clobber_all); 77 + } 78 + 79 + SEC("socket") 80 + __description("direct packet access: test3") 81 + __failure __msg("invalid bpf_context access off=76") 82 + __failure_unpriv 83 + __naked void direct_packet_access_test3(void) 84 + { 85 + asm volatile (" \ 86 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 87 + r0 = 0; \ 88 + exit; \ 89 + " : 90 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)) 91 + : __clobber_all); 92 + } 93 + 94 + SEC("tc") 95 + __description("direct packet access: test4 (write)") 96 + __success __retval(0) 97 + __naked void direct_packet_access_test4_write(void) 98 + { 99 + asm volatile (" \ 100 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 101 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 102 + r0 = r2; \ 103 + r0 += 8; \ 104 + if r0 > r3 goto l0_%=; \ 105 + *(u8*)(r2 + 0) = r2; \ 106 + l0_%=: r0 = 0; \ 107 + exit; \ 108 + " : 109 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 110 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 111 + : __clobber_all); 112 + } 113 + 114 + SEC("tc") 115 + __description("direct packet access: test5 (pkt_end >= reg, good access)") 116 + __success __retval(0) 117 + __naked void pkt_end_reg_good_access(void) 118 + { 119 + asm volatile (" \ 120 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 121 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 122 + r0 = r2; \ 123 + r0 += 8; \ 124 + if r3 >= r0 goto l0_%=; \ 125 + r0 = 1; \ 126 + exit; \ 127 + l0_%=: r0 = *(u8*)(r2 + 0); \ 128 + r0 = 0; \ 129 + exit; \ 130 + " : 131 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 132 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 133 + : __clobber_all); 134 + } 135 + 136 + SEC("tc") 137 + __description("direct packet access: test6 (pkt_end >= reg, bad access)") 138 + __failure __msg("invalid access to packet") 139 + __naked void pkt_end_reg_bad_access(void) 140 + { 141 + asm volatile (" \ 142 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 143 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 144 + r0 = r2; \ 145 + r0 += 8; \ 146 + if r3 >= r0 goto l0_%=; \ 147 + r0 = *(u8*)(r2 + 0); \ 148 + r0 = 1; \ 149 + exit; \ 150 + l0_%=: r0 = 0; \ 151 + exit; \ 152 + " : 153 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 154 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 155 + : __clobber_all); 156 + } 157 + 158 + SEC("tc") 159 + __description("direct packet access: test7 (pkt_end >= reg, both accesses)") 160 + __failure __msg("invalid access to packet") 161 + __naked void pkt_end_reg_both_accesses(void) 162 + { 163 + asm volatile (" \ 164 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 165 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 166 + r0 = r2; \ 167 + r0 += 8; \ 168 + if r3 >= r0 goto l0_%=; \ 169 + r0 = *(u8*)(r2 + 0); \ 170 + r0 = 1; \ 171 + exit; \ 172 + l0_%=: r0 = *(u8*)(r2 + 0); \ 173 + r0 = 0; \ 174 + exit; \ 175 + " : 176 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 177 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 178 + : __clobber_all); 179 + } 180 + 181 + SEC("tc") 182 + __description("direct packet access: test8 (double test, variant 1)") 183 + __success __retval(0) 184 + __naked void test8_double_test_variant_1(void) 185 + { 186 + asm volatile (" \ 187 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 188 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 189 + r0 = r2; \ 190 + r0 += 8; \ 191 + if r3 >= r0 goto l0_%=; \ 192 + if r0 > r3 goto l1_%=; \ 193 + r0 = *(u8*)(r2 + 0); \ 194 + l1_%=: r0 = 1; \ 195 + exit; \ 196 + l0_%=: r0 = *(u8*)(r2 + 0); \ 197 + r0 = 0; \ 198 + exit; \ 199 + " : 200 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 201 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 202 + : __clobber_all); 203 + } 204 + 205 + SEC("tc") 206 + __description("direct packet access: test9 (double test, variant 2)") 207 + __success __retval(0) 208 + __naked void test9_double_test_variant_2(void) 209 + { 210 + asm volatile (" \ 211 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 212 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 213 + r0 = r2; \ 214 + r0 += 8; \ 215 + if r3 >= r0 goto l0_%=; \ 216 + r0 = 1; \ 217 + exit; \ 218 + l0_%=: if r0 > r3 goto l1_%=; \ 219 + r0 = *(u8*)(r2 + 0); \ 220 + l1_%=: r0 = *(u8*)(r2 + 0); \ 221 + r0 = 0; \ 222 + exit; \ 223 + " : 224 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 225 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 226 + : __clobber_all); 227 + } 228 + 229 + SEC("tc") 230 + __description("direct packet access: test10 (write invalid)") 231 + __failure __msg("invalid access to packet") 232 + __naked void packet_access_test10_write_invalid(void) 233 + { 234 + asm volatile (" \ 235 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 236 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 237 + r0 = r2; \ 238 + r0 += 8; \ 239 + if r0 > r3 goto l0_%=; \ 240 + r0 = 0; \ 241 + exit; \ 242 + l0_%=: *(u8*)(r2 + 0) = r2; \ 243 + r0 = 0; \ 244 + exit; \ 245 + " : 246 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 247 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 248 + : __clobber_all); 249 + } 250 + 251 + SEC("tc") 252 + __description("direct packet access: test11 (shift, good access)") 253 + __success __retval(1) 254 + __naked void access_test11_shift_good_access(void) 255 + { 256 + asm volatile (" \ 257 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 258 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 259 + r0 = r2; \ 260 + r0 += 22; \ 261 + if r0 > r3 goto l0_%=; \ 262 + r3 = 144; \ 263 + r5 = r3; \ 264 + r5 += 23; \ 265 + r5 >>= 3; \ 266 + r6 = r2; \ 267 + r6 += r5; \ 268 + r0 = 1; \ 269 + exit; \ 270 + l0_%=: r0 = 0; \ 271 + exit; \ 272 + " : 273 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 274 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 275 + : __clobber_all); 276 + } 277 + 278 + SEC("tc") 279 + __description("direct packet access: test12 (and, good access)") 280 + __success __retval(1) 281 + __naked void access_test12_and_good_access(void) 282 + { 283 + asm volatile (" \ 284 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 285 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 286 + r0 = r2; \ 287 + r0 += 22; \ 288 + if r0 > r3 goto l0_%=; \ 289 + r3 = 144; \ 290 + r5 = r3; \ 291 + r5 += 23; \ 292 + r5 &= 15; \ 293 + r6 = r2; \ 294 + r6 += r5; \ 295 + r0 = 1; \ 296 + exit; \ 297 + l0_%=: r0 = 0; \ 298 + exit; \ 299 + " : 300 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 301 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 302 + : __clobber_all); 303 + } 304 + 305 + SEC("tc") 306 + __description("direct packet access: test13 (branches, good access)") 307 + __success __retval(1) 308 + __naked void access_test13_branches_good_access(void) 309 + { 310 + asm volatile (" \ 311 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 312 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 313 + r0 = r2; \ 314 + r0 += 22; \ 315 + if r0 > r3 goto l0_%=; \ 316 + r3 = *(u32*)(r1 + %[__sk_buff_mark]); \ 317 + r4 = 1; \ 318 + if r3 > r4 goto l1_%=; \ 319 + r3 = 14; \ 320 + goto l2_%=; \ 321 + l1_%=: r3 = 24; \ 322 + l2_%=: r5 = r3; \ 323 + r5 += 23; \ 324 + r5 &= 15; \ 325 + r6 = r2; \ 326 + r6 += r5; \ 327 + r0 = 1; \ 328 + exit; \ 329 + l0_%=: r0 = 0; \ 330 + exit; \ 331 + " : 332 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 333 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)), 334 + __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 335 + : __clobber_all); 336 + } 337 + 338 + SEC("tc") 339 + __description("direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)") 340 + __success __retval(1) 341 + __naked void _0_const_imm_good_access(void) 342 + { 343 + asm volatile (" \ 344 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 345 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 346 + r0 = r2; \ 347 + r0 += 22; \ 348 + if r0 > r3 goto l0_%=; \ 349 + r5 = 12; \ 350 + r5 >>= 4; \ 351 + r6 = r2; \ 352 + r6 += r5; \ 353 + r0 = *(u8*)(r6 + 0); \ 354 + r0 = 1; \ 355 + exit; \ 356 + l0_%=: r0 = 0; \ 357 + exit; \ 358 + " : 359 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 360 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 361 + : __clobber_all); 362 + } 363 + 364 + SEC("tc") 365 + __description("direct packet access: test15 (spill with xadd)") 366 + __failure __msg("R2 invalid mem access 'scalar'") 367 + __flag(BPF_F_ANY_ALIGNMENT) 368 + __naked void access_test15_spill_with_xadd(void) 369 + { 370 + asm volatile (" \ 371 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 372 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 373 + r0 = r2; \ 374 + r0 += 8; \ 375 + if r0 > r3 goto l0_%=; \ 376 + r5 = 4096; \ 377 + r4 = r10; \ 378 + r4 += -8; \ 379 + *(u64*)(r4 + 0) = r2; \ 380 + lock *(u64 *)(r4 + 0) += r5; \ 381 + r2 = *(u64*)(r4 + 0); \ 382 + *(u32*)(r2 + 0) = r5; \ 383 + r0 = 0; \ 384 + l0_%=: exit; \ 385 + " : 386 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 387 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 388 + : __clobber_all); 389 + } 390 + 391 + SEC("tc") 392 + __description("direct packet access: test16 (arith on data_end)") 393 + __failure __msg("R3 pointer arithmetic on pkt_end") 394 + __naked void test16_arith_on_data_end(void) 395 + { 396 + asm volatile (" \ 397 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 398 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 399 + r0 = r2; \ 400 + r0 += 8; \ 401 + r3 += 16; \ 402 + if r0 > r3 goto l0_%=; \ 403 + *(u8*)(r2 + 0) = r2; \ 404 + l0_%=: r0 = 0; \ 405 + exit; \ 406 + " : 407 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 408 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 409 + : __clobber_all); 410 + } 411 + 412 + SEC("tc") 413 + __description("direct packet access: test17 (pruning, alignment)") 414 + __failure __msg("misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4") 415 + __flag(BPF_F_STRICT_ALIGNMENT) 416 + __naked void packet_access_test17_pruning_alignment(void) 417 + { 418 + asm volatile (" \ 419 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 420 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 421 + r7 = *(u32*)(r1 + %[__sk_buff_mark]); \ 422 + r0 = r2; \ 423 + r0 += 14; \ 424 + if r7 > 1 goto l0_%=; \ 425 + l2_%=: if r0 > r3 goto l1_%=; \ 426 + *(u32*)(r0 - 4) = r0; \ 427 + l1_%=: r0 = 0; \ 428 + exit; \ 429 + l0_%=: r0 += 1; \ 430 + goto l2_%=; \ 431 + " : 432 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 433 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)), 434 + __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 435 + : __clobber_all); 436 + } 437 + 438 + SEC("tc") 439 + __description("direct packet access: test18 (imm += pkt_ptr, 1)") 440 + __success __retval(0) 441 + __naked void test18_imm_pkt_ptr_1(void) 442 + { 443 + asm volatile (" \ 444 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 445 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 446 + r0 = 8; \ 447 + r0 += r2; \ 448 + if r0 > r3 goto l0_%=; \ 449 + *(u8*)(r2 + 0) = r2; \ 450 + l0_%=: r0 = 0; \ 451 + exit; \ 452 + " : 453 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 454 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 455 + : __clobber_all); 456 + } 457 + 458 + SEC("tc") 459 + __description("direct packet access: test19 (imm += pkt_ptr, 2)") 460 + __success __retval(0) 461 + __naked void test19_imm_pkt_ptr_2(void) 462 + { 463 + asm volatile (" \ 464 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 465 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 466 + r0 = r2; \ 467 + r0 += 8; \ 468 + if r0 > r3 goto l0_%=; \ 469 + r4 = 4; \ 470 + r4 += r2; \ 471 + *(u8*)(r4 + 0) = r4; \ 472 + l0_%=: r0 = 0; \ 473 + exit; \ 474 + " : 475 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 476 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 477 + : __clobber_all); 478 + } 479 + 480 + SEC("tc") 481 + __description("direct packet access: test20 (x += pkt_ptr, 1)") 482 + __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 483 + __naked void test20_x_pkt_ptr_1(void) 484 + { 485 + asm volatile (" \ 486 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 487 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 488 + r0 = 0xffffffff; \ 489 + *(u64*)(r10 - 8) = r0; \ 490 + r0 = *(u64*)(r10 - 8); \ 491 + r0 &= 0x7fff; \ 492 + r4 = r0; \ 493 + r4 += r2; \ 494 + r5 = r4; \ 495 + r4 += %[__imm_0]; \ 496 + if r4 > r3 goto l0_%=; \ 497 + *(u64*)(r5 + 0) = r4; \ 498 + l0_%=: r0 = 0; \ 499 + exit; \ 500 + " : 501 + : __imm_const(__imm_0, 0x7fff - 1), 502 + __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 503 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 504 + : __clobber_all); 505 + } 506 + 507 + SEC("tc") 508 + __description("direct packet access: test21 (x += pkt_ptr, 2)") 509 + __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 510 + __naked void test21_x_pkt_ptr_2(void) 511 + { 512 + asm volatile (" \ 513 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 514 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 515 + r0 = r2; \ 516 + r0 += 8; \ 517 + if r0 > r3 goto l0_%=; \ 518 + r4 = 0xffffffff; \ 519 + *(u64*)(r10 - 8) = r4; \ 520 + r4 = *(u64*)(r10 - 8); \ 521 + r4 &= 0x7fff; \ 522 + r4 += r2; \ 523 + r5 = r4; \ 524 + r4 += %[__imm_0]; \ 525 + if r4 > r3 goto l0_%=; \ 526 + *(u64*)(r5 + 0) = r4; \ 527 + l0_%=: r0 = 0; \ 528 + exit; \ 529 + " : 530 + : __imm_const(__imm_0, 0x7fff - 1), 531 + __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 532 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 533 + : __clobber_all); 534 + } 535 + 536 + SEC("tc") 537 + __description("direct packet access: test22 (x += pkt_ptr, 3)") 538 + __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 539 + __naked void test22_x_pkt_ptr_3(void) 540 + { 541 + asm volatile (" \ 542 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 543 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 544 + r0 = r2; \ 545 + r0 += 8; \ 546 + *(u64*)(r10 - 8) = r2; \ 547 + *(u64*)(r10 - 16) = r3; \ 548 + r3 = *(u64*)(r10 - 16); \ 549 + if r0 > r3 goto l0_%=; \ 550 + r2 = *(u64*)(r10 - 8); \ 551 + r4 = 0xffffffff; \ 552 + lock *(u64 *)(r10 - 8) += r4; \ 553 + r4 = *(u64*)(r10 - 8); \ 554 + r4 >>= 49; \ 555 + r4 += r2; \ 556 + r0 = r4; \ 557 + r0 += 2; \ 558 + if r0 > r3 goto l0_%=; \ 559 + r2 = 1; \ 560 + *(u16*)(r4 + 0) = r2; \ 561 + l0_%=: r0 = 0; \ 562 + exit; \ 563 + " : 564 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 565 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 566 + : __clobber_all); 567 + } 568 + 569 + SEC("tc") 570 + __description("direct packet access: test23 (x += pkt_ptr, 4)") 571 + __failure __msg("invalid access to packet, off=0 size=8, R5(id=2,off=0,r=0)") 572 + __flag(BPF_F_ANY_ALIGNMENT) 573 + __naked void test23_x_pkt_ptr_4(void) 574 + { 575 + asm volatile (" \ 576 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 577 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 578 + r0 = *(u32*)(r1 + %[__sk_buff_mark]); \ 579 + *(u64*)(r10 - 8) = r0; \ 580 + r0 = *(u64*)(r10 - 8); \ 581 + r0 &= 0xffff; \ 582 + r4 = r0; \ 583 + r0 = 31; \ 584 + r0 += r4; \ 585 + r0 += r2; \ 586 + r5 = r0; \ 587 + r0 += %[__imm_0]; \ 588 + if r0 > r3 goto l0_%=; \ 589 + *(u64*)(r5 + 0) = r0; \ 590 + l0_%=: r0 = 0; \ 591 + exit; \ 592 + " : 593 + : __imm_const(__imm_0, 0xffff - 1), 594 + __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 595 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)), 596 + __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 597 + : __clobber_all); 598 + } 599 + 600 + SEC("tc") 601 + __description("direct packet access: test24 (x += pkt_ptr, 5)") 602 + __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 603 + __naked void test24_x_pkt_ptr_5(void) 604 + { 605 + asm volatile (" \ 606 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 607 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 608 + r0 = 0xffffffff; \ 609 + *(u64*)(r10 - 8) = r0; \ 610 + r0 = *(u64*)(r10 - 8); \ 611 + r0 &= 0xff; \ 612 + r4 = r0; \ 613 + r0 = 64; \ 614 + r0 += r4; \ 615 + r0 += r2; \ 616 + r5 = r0; \ 617 + r0 += %[__imm_0]; \ 618 + if r0 > r3 goto l0_%=; \ 619 + *(u64*)(r5 + 0) = r0; \ 620 + l0_%=: r0 = 0; \ 621 + exit; \ 622 + " : 623 + : __imm_const(__imm_0, 0x7fff - 1), 624 + __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 625 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 626 + : __clobber_all); 627 + } 628 + 629 + SEC("tc") 630 + __description("direct packet access: test25 (marking on <, good access)") 631 + __success __retval(0) 632 + __naked void test25_marking_on_good_access(void) 633 + { 634 + asm volatile (" \ 635 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 636 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 637 + r0 = r2; \ 638 + r0 += 8; \ 639 + if r0 < r3 goto l0_%=; \ 640 + l1_%=: r0 = 0; \ 641 + exit; \ 642 + l0_%=: r0 = *(u8*)(r2 + 0); \ 643 + goto l1_%=; \ 644 + " : 645 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 646 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 647 + : __clobber_all); 648 + } 649 + 650 + SEC("tc") 651 + __description("direct packet access: test26 (marking on <, bad access)") 652 + __failure __msg("invalid access to packet") 653 + __naked void test26_marking_on_bad_access(void) 654 + { 655 + asm volatile (" \ 656 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 657 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 658 + r0 = r2; \ 659 + r0 += 8; \ 660 + if r0 < r3 goto l0_%=; \ 661 + r0 = *(u8*)(r2 + 0); \ 662 + l1_%=: r0 = 0; \ 663 + exit; \ 664 + l0_%=: goto l1_%=; \ 665 + " : 666 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 667 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 668 + : __clobber_all); 669 + } 670 + 671 + SEC("tc") 672 + __description("direct packet access: test27 (marking on <=, good access)") 673 + __success __retval(1) 674 + __naked void test27_marking_on_good_access(void) 675 + { 676 + asm volatile (" \ 677 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 678 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 679 + r0 = r2; \ 680 + r0 += 8; \ 681 + if r3 <= r0 goto l0_%=; \ 682 + r0 = *(u8*)(r2 + 0); \ 683 + l0_%=: r0 = 1; \ 684 + exit; \ 685 + " : 686 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 687 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 688 + : __clobber_all); 689 + } 690 + 691 + SEC("tc") 692 + __description("direct packet access: test28 (marking on <=, bad access)") 693 + __failure __msg("invalid access to packet") 694 + __naked void test28_marking_on_bad_access(void) 695 + { 696 + asm volatile (" \ 697 + r2 = *(u32*)(r1 + %[__sk_buff_data]); \ 698 + r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 699 + r0 = r2; \ 700 + r0 += 8; \ 701 + if r3 <= r0 goto l0_%=; \ 702 + l1_%=: r0 = 1; \ 703 + exit; \ 704 + l0_%=: r0 = *(u8*)(r2 + 0); \ 705 + goto l1_%=; \ 706 + " : 707 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 708 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 709 + : __clobber_all); 710 + } 711 + 712 + SEC("tc") 713 + __description("direct packet access: test29 (reg > pkt_end in subprog)") 714 + __success __retval(0) 715 + __naked void reg_pkt_end_in_subprog(void) 716 + { 717 + asm volatile (" \ 718 + r6 = *(u32*)(r1 + %[__sk_buff_data]); \ 719 + r2 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 720 + r3 = r6; \ 721 + r3 += 8; \ 722 + call reg_pkt_end_in_subprog__1; \ 723 + if r0 == 0 goto l0_%=; \ 724 + r0 = *(u8*)(r6 + 0); \ 725 + l0_%=: r0 = 0; \ 726 + exit; \ 727 + " : 728 + : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 729 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 730 + : __clobber_all); 731 + } 732 + 733 + static __naked __noinline __attribute__((used)) 734 + void reg_pkt_end_in_subprog__1(void) 735 + { 736 + asm volatile (" \ 737 + r0 = 0; \ 738 + if r3 > r2 goto l0_%=; \ 739 + r0 = 1; \ 740 + l0_%=: exit; \ 741 + " ::: __clobber_all); 742 + } 743 + 744 + SEC("tc") 745 + __description("direct packet access: test30 (check_id() in regsafe(), bad access)") 746 + __failure __msg("invalid access to packet, off=0 size=1, R2") 747 + __flag(BPF_F_TEST_STATE_FREQ) 748 + __naked void id_in_regsafe_bad_access(void) 749 + { 750 + asm volatile (" \ 751 + /* r9 = ctx */ \ 752 + r9 = r1; \ 753 + /* r7 = ktime_get_ns() */ \ 754 + call %[bpf_ktime_get_ns]; \ 755 + r7 = r0; \ 756 + /* r6 = ktime_get_ns() */ \ 757 + call %[bpf_ktime_get_ns]; \ 758 + r6 = r0; \ 759 + /* r2 = ctx->data \ 760 + * r3 = ctx->data \ 761 + * r4 = ctx->data_end \ 762 + */ \ 763 + r2 = *(u32*)(r9 + %[__sk_buff_data]); \ 764 + r3 = *(u32*)(r9 + %[__sk_buff_data]); \ 765 + r4 = *(u32*)(r9 + %[__sk_buff_data_end]); \ 766 + /* if r6 > 100 goto exit \ 767 + * if r7 > 100 goto exit \ 768 + */ \ 769 + if r6 > 100 goto l0_%=; \ 770 + if r7 > 100 goto l0_%=; \ 771 + /* r2 += r6 ; this forces assignment of ID to r2\ 772 + * r2 += 1 ; get some fixed off for r2\ 773 + * r3 += r7 ; this forces assignment of ID to r3\ 774 + * r3 += 1 ; get some fixed off for r3\ 775 + */ \ 776 + r2 += r6; \ 777 + r2 += 1; \ 778 + r3 += r7; \ 779 + r3 += 1; \ 780 + /* if r6 > r7 goto +1 ; no new information about the state is derived from\ 781 + * ; this check, thus produced verifier states differ\ 782 + * ; only in 'insn_idx' \ 783 + * r2 = r3 ; optionally share ID between r2 and r3\ 784 + */ \ 785 + if r6 != r7 goto l1_%=; \ 786 + r2 = r3; \ 787 + l1_%=: /* if r3 > ctx->data_end goto exit */ \ 788 + if r3 > r4 goto l0_%=; \ 789 + /* r5 = *(u8 *) (r2 - 1) ; access packet memory using r2,\ 790 + * ; this is not always safe\ 791 + */ \ 792 + r5 = *(u8*)(r2 - 1); \ 793 + l0_%=: /* exit(0) */ \ 794 + r0 = 0; \ 795 + exit; \ 796 + " : 797 + : __imm(bpf_ktime_get_ns), 798 + __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 799 + __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 800 + : __clobber_all); 801 + } 802 + 803 + char _license[] SEC("license") = "GPL";
-710
tools/testing/selftests/bpf/verifier/direct_packet_access.c
··· 1 - { 2 - "pkt_end - pkt_start is allowed", 3 - .insns = { 4 - BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 5 - offsetof(struct __sk_buff, data_end)), 6 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7 - offsetof(struct __sk_buff, data)), 8 - BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2), 9 - BPF_EXIT_INSN(), 10 - }, 11 - .result = ACCEPT, 12 - .retval = TEST_DATA_LEN, 13 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 14 - }, 15 - { 16 - "direct packet access: test1", 17 - .insns = { 18 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 19 - offsetof(struct __sk_buff, data)), 20 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 21 - offsetof(struct __sk_buff, data_end)), 22 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 23 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 24 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 25 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 26 - BPF_MOV64_IMM(BPF_REG_0, 0), 27 - BPF_EXIT_INSN(), 28 - }, 29 - .result = ACCEPT, 30 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 31 - }, 32 - { 33 - "direct packet access: test2", 34 - .insns = { 35 - BPF_MOV64_IMM(BPF_REG_0, 1), 36 - BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 37 - offsetof(struct __sk_buff, data_end)), 38 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 39 - offsetof(struct __sk_buff, data)), 40 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_3), 41 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14), 42 - BPF_JMP_REG(BPF_JGT, BPF_REG_5, BPF_REG_4, 15), 43 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_3, 7), 44 - BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_3, 12), 45 - BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 14), 46 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 47 - offsetof(struct __sk_buff, data)), 48 - BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_4), 49 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 50 - offsetof(struct __sk_buff, len)), 51 - BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 49), 52 - BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 49), 53 - BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2), 54 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_3), 55 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 56 - BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 57 - offsetof(struct __sk_buff, data_end)), 58 - BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1), 59 - BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_3, 4), 60 - BPF_MOV64_IMM(BPF_REG_0, 0), 61 - BPF_EXIT_INSN(), 62 - }, 63 - .result = ACCEPT, 64 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 65 - }, 66 - { 67 - "direct packet access: test3", 68 - .insns = { 69 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 70 - offsetof(struct __sk_buff, data)), 71 - BPF_MOV64_IMM(BPF_REG_0, 0), 72 - BPF_EXIT_INSN(), 73 - }, 74 - .errstr = "invalid bpf_context access off=76", 75 - .result = REJECT, 76 - .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 77 - }, 78 - { 79 - "direct packet access: test4 (write)", 80 - .insns = { 81 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 82 - offsetof(struct __sk_buff, data)), 83 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 84 - offsetof(struct __sk_buff, data_end)), 85 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 86 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 87 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 88 - BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 89 - BPF_MOV64_IMM(BPF_REG_0, 0), 90 - BPF_EXIT_INSN(), 91 - }, 92 - .result = ACCEPT, 93 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 94 - }, 95 - { 96 - "direct packet access: test5 (pkt_end >= reg, good access)", 97 - .insns = { 98 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 99 - offsetof(struct __sk_buff, data)), 100 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 101 - offsetof(struct __sk_buff, data_end)), 102 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 103 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 104 - BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2), 105 - BPF_MOV64_IMM(BPF_REG_0, 1), 106 - BPF_EXIT_INSN(), 107 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 108 - BPF_MOV64_IMM(BPF_REG_0, 0), 109 - BPF_EXIT_INSN(), 110 - }, 111 - .result = ACCEPT, 112 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 113 - }, 114 - { 115 - "direct packet access: test6 (pkt_end >= reg, bad access)", 116 - .insns = { 117 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 118 - offsetof(struct __sk_buff, data)), 119 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 120 - offsetof(struct __sk_buff, data_end)), 121 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 122 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 123 - BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3), 124 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 125 - BPF_MOV64_IMM(BPF_REG_0, 1), 126 - BPF_EXIT_INSN(), 127 - BPF_MOV64_IMM(BPF_REG_0, 0), 128 - BPF_EXIT_INSN(), 129 - }, 130 - .errstr = "invalid access to packet", 131 - .result = REJECT, 132 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 133 - }, 134 - { 135 - "direct packet access: test7 (pkt_end >= reg, both accesses)", 136 - .insns = { 137 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 138 - offsetof(struct __sk_buff, data)), 139 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 140 - offsetof(struct __sk_buff, data_end)), 141 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 142 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 143 - BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 3), 144 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 145 - BPF_MOV64_IMM(BPF_REG_0, 1), 146 - BPF_EXIT_INSN(), 147 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 148 - BPF_MOV64_IMM(BPF_REG_0, 0), 149 - BPF_EXIT_INSN(), 150 - }, 151 - .errstr = "invalid access to packet", 152 - .result = REJECT, 153 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 154 - }, 155 - { 156 - "direct packet access: test8 (double test, variant 1)", 157 - .insns = { 158 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 159 - offsetof(struct __sk_buff, data)), 160 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 161 - offsetof(struct __sk_buff, data_end)), 162 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 163 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 164 - BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 4), 165 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 166 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 167 - BPF_MOV64_IMM(BPF_REG_0, 1), 168 - BPF_EXIT_INSN(), 169 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 170 - BPF_MOV64_IMM(BPF_REG_0, 0), 171 - BPF_EXIT_INSN(), 172 - }, 173 - .result = ACCEPT, 174 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 175 - }, 176 - { 177 - "direct packet access: test9 (double test, variant 2)", 178 - .insns = { 179 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 180 - offsetof(struct __sk_buff, data)), 181 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 182 - offsetof(struct __sk_buff, data_end)), 183 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 184 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 185 - BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 2), 186 - BPF_MOV64_IMM(BPF_REG_0, 1), 187 - BPF_EXIT_INSN(), 188 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 189 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 190 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 191 - BPF_MOV64_IMM(BPF_REG_0, 0), 192 - BPF_EXIT_INSN(), 193 - }, 194 - .result = ACCEPT, 195 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 196 - }, 197 - { 198 - "direct packet access: test10 (write invalid)", 199 - .insns = { 200 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 201 - offsetof(struct __sk_buff, data)), 202 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 203 - offsetof(struct __sk_buff, data_end)), 204 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 205 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 206 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 207 - BPF_MOV64_IMM(BPF_REG_0, 0), 208 - BPF_EXIT_INSN(), 209 - BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 210 - BPF_MOV64_IMM(BPF_REG_0, 0), 211 - BPF_EXIT_INSN(), 212 - }, 213 - .errstr = "invalid access to packet", 214 - .result = REJECT, 215 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 216 - }, 217 - { 218 - "direct packet access: test11 (shift, good access)", 219 - .insns = { 220 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 221 - offsetof(struct __sk_buff, data)), 222 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 223 - offsetof(struct __sk_buff, data_end)), 224 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 225 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22), 226 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8), 227 - BPF_MOV64_IMM(BPF_REG_3, 144), 228 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_3), 229 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23), 230 - BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3), 231 - BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 232 - BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5), 233 - BPF_MOV64_IMM(BPF_REG_0, 1), 234 - BPF_EXIT_INSN(), 235 - BPF_MOV64_IMM(BPF_REG_0, 0), 236 - BPF_EXIT_INSN(), 237 - }, 238 - .result = ACCEPT, 239 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 240 - .retval = 1, 241 - }, 242 - { 243 - "direct packet access: test12 (and, good access)", 244 - .insns = { 245 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 246 - offsetof(struct __sk_buff, data)), 247 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 248 - offsetof(struct __sk_buff, data_end)), 249 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 250 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22), 251 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8), 252 - BPF_MOV64_IMM(BPF_REG_3, 144), 253 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_3), 254 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23), 255 - BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15), 256 - BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 257 - BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5), 258 - BPF_MOV64_IMM(BPF_REG_0, 1), 259 - BPF_EXIT_INSN(), 260 - BPF_MOV64_IMM(BPF_REG_0, 0), 261 - BPF_EXIT_INSN(), 262 - }, 263 - .result = ACCEPT, 264 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 265 - .retval = 1, 266 - }, 267 - { 268 - "direct packet access: test13 (branches, good access)", 269 - .insns = { 270 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 271 - offsetof(struct __sk_buff, data)), 272 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 273 - offsetof(struct __sk_buff, data_end)), 274 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 275 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22), 276 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13), 277 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 278 - offsetof(struct __sk_buff, mark)), 279 - BPF_MOV64_IMM(BPF_REG_4, 1), 280 - BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2), 281 - BPF_MOV64_IMM(BPF_REG_3, 14), 282 - BPF_JMP_IMM(BPF_JA, 0, 0, 1), 283 - BPF_MOV64_IMM(BPF_REG_3, 24), 284 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_3), 285 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23), 286 - BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15), 287 - BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 288 - BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5), 289 - BPF_MOV64_IMM(BPF_REG_0, 1), 290 - BPF_EXIT_INSN(), 291 - BPF_MOV64_IMM(BPF_REG_0, 0), 292 - BPF_EXIT_INSN(), 293 - }, 294 - .result = ACCEPT, 295 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 296 - .retval = 1, 297 - }, 298 - { 299 - "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)", 300 - .insns = { 301 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 302 - offsetof(struct __sk_buff, data)), 303 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 304 - offsetof(struct __sk_buff, data_end)), 305 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 306 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22), 307 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7), 308 - BPF_MOV64_IMM(BPF_REG_5, 12), 309 - BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4), 310 - BPF_MOV64_REG(BPF_REG_6, BPF_REG_2), 311 - BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5), 312 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), 313 - BPF_MOV64_IMM(BPF_REG_0, 1), 314 - BPF_EXIT_INSN(), 315 - BPF_MOV64_IMM(BPF_REG_0, 0), 316 - BPF_EXIT_INSN(), 317 - }, 318 - .result = ACCEPT, 319 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 320 - .retval = 1, 321 - }, 322 - { 323 - "direct packet access: test15 (spill with xadd)", 324 - .insns = { 325 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 326 - offsetof(struct __sk_buff, data)), 327 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 328 - offsetof(struct __sk_buff, data_end)), 329 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 330 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 331 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8), 332 - BPF_MOV64_IMM(BPF_REG_5, 4096), 333 - BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), 334 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), 335 - BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), 336 - BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_4, BPF_REG_5, 0), 337 - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), 338 - BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0), 339 - BPF_MOV64_IMM(BPF_REG_0, 0), 340 - BPF_EXIT_INSN(), 341 - }, 342 - .errstr = "R2 invalid mem access 'scalar'", 343 - .result = REJECT, 344 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 345 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 346 - }, 347 - { 348 - "direct packet access: test16 (arith on data_end)", 349 - .insns = { 350 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 351 - offsetof(struct __sk_buff, data)), 352 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 353 - offsetof(struct __sk_buff, data_end)), 354 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 355 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 356 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 16), 357 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 358 - BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 359 - BPF_MOV64_IMM(BPF_REG_0, 0), 360 - BPF_EXIT_INSN(), 361 - }, 362 - .errstr = "R3 pointer arithmetic on pkt_end", 363 - .result = REJECT, 364 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 365 - }, 366 - { 367 - "direct packet access: test17 (pruning, alignment)", 368 - .insns = { 369 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 370 - offsetof(struct __sk_buff, data)), 371 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 372 - offsetof(struct __sk_buff, data_end)), 373 - BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, 374 - offsetof(struct __sk_buff, mark)), 375 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 376 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 14), 377 - BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 1, 4), 378 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 379 - BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, -4), 380 - BPF_MOV64_IMM(BPF_REG_0, 0), 381 - BPF_EXIT_INSN(), 382 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 383 - BPF_JMP_A(-6), 384 - }, 385 - .errstr = "misaligned packet access off 2+(0x0; 0x0)+15+-4 size 4", 386 - .result = REJECT, 387 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 388 - .flags = F_LOAD_WITH_STRICT_ALIGNMENT, 389 - }, 390 - { 391 - "direct packet access: test18 (imm += pkt_ptr, 1)", 392 - .insns = { 393 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 394 - offsetof(struct __sk_buff, data)), 395 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 396 - offsetof(struct __sk_buff, data_end)), 397 - BPF_MOV64_IMM(BPF_REG_0, 8), 398 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 399 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 400 - BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0), 401 - BPF_MOV64_IMM(BPF_REG_0, 0), 402 - BPF_EXIT_INSN(), 403 - }, 404 - .result = ACCEPT, 405 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 406 - }, 407 - { 408 - "direct packet access: test19 (imm += pkt_ptr, 2)", 409 - .insns = { 410 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 411 - offsetof(struct __sk_buff, data)), 412 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 413 - offsetof(struct __sk_buff, data_end)), 414 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 415 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 416 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3), 417 - BPF_MOV64_IMM(BPF_REG_4, 4), 418 - BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2), 419 - BPF_STX_MEM(BPF_B, BPF_REG_4, BPF_REG_4, 0), 420 - BPF_MOV64_IMM(BPF_REG_0, 0), 421 - BPF_EXIT_INSN(), 422 - }, 423 - .result = ACCEPT, 424 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 425 - }, 426 - { 427 - "direct packet access: test20 (x += pkt_ptr, 1)", 428 - .insns = { 429 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 430 - offsetof(struct __sk_buff, data)), 431 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 432 - offsetof(struct __sk_buff, data_end)), 433 - BPF_MOV64_IMM(BPF_REG_0, 0xffffffff), 434 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 435 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 436 - BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0x7fff), 437 - BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 438 - BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2), 439 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_4), 440 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1), 441 - BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1), 442 - BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0), 443 - BPF_MOV64_IMM(BPF_REG_0, 0), 444 - BPF_EXIT_INSN(), 445 - }, 446 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 447 - .result = ACCEPT, 448 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 449 - }, 450 - { 451 - "direct packet access: test21 (x += pkt_ptr, 2)", 452 - .insns = { 453 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 454 - offsetof(struct __sk_buff, data)), 455 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 456 - offsetof(struct __sk_buff, data_end)), 457 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 458 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 459 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9), 460 - BPF_MOV64_IMM(BPF_REG_4, 0xffffffff), 461 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -8), 462 - BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 463 - BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 0x7fff), 464 - BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2), 465 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_4), 466 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 0x7fff - 1), 467 - BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, 1), 468 - BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0), 469 - BPF_MOV64_IMM(BPF_REG_0, 0), 470 - BPF_EXIT_INSN(), 471 - }, 472 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 473 - .result = ACCEPT, 474 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 475 - }, 476 - { 477 - "direct packet access: test22 (x += pkt_ptr, 3)", 478 - .insns = { 479 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 480 - offsetof(struct __sk_buff, data)), 481 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 482 - offsetof(struct __sk_buff, data_end)), 483 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 484 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 485 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8), 486 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, -16), 487 - BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16), 488 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 11), 489 - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8), 490 - BPF_MOV64_IMM(BPF_REG_4, 0xffffffff), 491 - BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_10, BPF_REG_4, -8), 492 - BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 493 - BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 49), 494 - BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_2), 495 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_4), 496 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2), 497 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2), 498 - BPF_MOV64_IMM(BPF_REG_2, 1), 499 - BPF_STX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0), 500 - BPF_MOV64_IMM(BPF_REG_0, 0), 501 - BPF_EXIT_INSN(), 502 - }, 503 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 504 - .result = ACCEPT, 505 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 506 - }, 507 - { 508 - "direct packet access: test23 (x += pkt_ptr, 4)", 509 - .insns = { 510 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 511 - offsetof(struct __sk_buff, data)), 512 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 513 - offsetof(struct __sk_buff, data_end)), 514 - BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 515 - offsetof(struct __sk_buff, mark)), 516 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 517 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 518 - BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff), 519 - BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 520 - BPF_MOV64_IMM(BPF_REG_0, 31), 521 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4), 522 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 523 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_0), 524 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0xffff - 1), 525 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 526 - BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0), 527 - BPF_MOV64_IMM(BPF_REG_0, 0), 528 - BPF_EXIT_INSN(), 529 - }, 530 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 531 - .result = REJECT, 532 - .errstr = "invalid access to packet, off=0 size=8, R5(id=2,off=0,r=0)", 533 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 534 - }, 535 - { 536 - "direct packet access: test24 (x += pkt_ptr, 5)", 537 - .insns = { 538 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 539 - offsetof(struct __sk_buff, data)), 540 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 541 - offsetof(struct __sk_buff, data_end)), 542 - BPF_MOV64_IMM(BPF_REG_0, 0xffffffff), 543 - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), 544 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 545 - BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff), 546 - BPF_MOV64_REG(BPF_REG_4, BPF_REG_0), 547 - BPF_MOV64_IMM(BPF_REG_0, 64), 548 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4), 549 - BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2), 550 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_0), 551 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7fff - 1), 552 - BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1), 553 - BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_0, 0), 554 - BPF_MOV64_IMM(BPF_REG_0, 0), 555 - BPF_EXIT_INSN(), 556 - }, 557 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 558 - .result = ACCEPT, 559 - .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 560 - }, 561 - { 562 - "direct packet access: test25 (marking on <, good access)", 563 - .insns = { 564 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 565 - offsetof(struct __sk_buff, data)), 566 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 567 - offsetof(struct __sk_buff, data_end)), 568 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 569 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 570 - BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 2), 571 - BPF_MOV64_IMM(BPF_REG_0, 0), 572 - BPF_EXIT_INSN(), 573 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 574 - BPF_JMP_IMM(BPF_JA, 0, 0, -4), 575 - }, 576 - .result = ACCEPT, 577 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 578 - }, 579 - { 580 - "direct packet access: test26 (marking on <, bad access)", 581 - .insns = { 582 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 583 - offsetof(struct __sk_buff, data)), 584 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 585 - offsetof(struct __sk_buff, data_end)), 586 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 587 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 588 - BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_3, 3), 589 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 590 - BPF_MOV64_IMM(BPF_REG_0, 0), 591 - BPF_EXIT_INSN(), 592 - BPF_JMP_IMM(BPF_JA, 0, 0, -3), 593 - }, 594 - .result = REJECT, 595 - .errstr = "invalid access to packet", 596 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 597 - }, 598 - { 599 - "direct packet access: test27 (marking on <=, good access)", 600 - .insns = { 601 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 602 - offsetof(struct __sk_buff, data)), 603 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 604 - offsetof(struct __sk_buff, data_end)), 605 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 606 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 607 - BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 1), 608 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 609 - BPF_MOV64_IMM(BPF_REG_0, 1), 610 - BPF_EXIT_INSN(), 611 - }, 612 - .result = ACCEPT, 613 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 614 - .retval = 1, 615 - }, 616 - { 617 - "direct packet access: test28 (marking on <=, bad access)", 618 - .insns = { 619 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 620 - offsetof(struct __sk_buff, data)), 621 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 622 - offsetof(struct __sk_buff, data_end)), 623 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 624 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), 625 - BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_0, 2), 626 - BPF_MOV64_IMM(BPF_REG_0, 1), 627 - BPF_EXIT_INSN(), 628 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0), 629 - BPF_JMP_IMM(BPF_JA, 0, 0, -4), 630 - }, 631 - .result = REJECT, 632 - .errstr = "invalid access to packet", 633 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 634 - }, 635 - { 636 - "direct packet access: test29 (reg > pkt_end in subprog)", 637 - .insns = { 638 - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, 639 - offsetof(struct __sk_buff, data)), 640 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 641 - offsetof(struct __sk_buff, data_end)), 642 - BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), 643 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8), 644 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), 645 - BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), 646 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), 647 - BPF_MOV64_IMM(BPF_REG_0, 0), 648 - BPF_EXIT_INSN(), 649 - BPF_MOV64_IMM(BPF_REG_0, 0), 650 - BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_2, 1), 651 - BPF_MOV64_IMM(BPF_REG_0, 1), 652 - BPF_EXIT_INSN(), 653 - }, 654 - .result = ACCEPT, 655 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 656 - }, 657 - { 658 - "direct packet access: test30 (check_id() in regsafe(), bad access)", 659 - .insns = { 660 - /* r9 = ctx */ 661 - BPF_MOV64_REG(BPF_REG_9, BPF_REG_1), 662 - /* r7 = ktime_get_ns() */ 663 - BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 664 - BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), 665 - /* r6 = ktime_get_ns() */ 666 - BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), 667 - BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), 668 - /* r2 = ctx->data 669 - * r3 = ctx->data 670 - * r4 = ctx->data_end 671 - */ 672 - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_9, offsetof(struct __sk_buff, data)), 673 - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_9, offsetof(struct __sk_buff, data)), 674 - BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_9, offsetof(struct __sk_buff, data_end)), 675 - /* if r6 > 100 goto exit 676 - * if r7 > 100 goto exit 677 - */ 678 - BPF_JMP_IMM(BPF_JGT, BPF_REG_6, 100, 9), 679 - BPF_JMP_IMM(BPF_JGT, BPF_REG_7, 100, 8), 680 - /* r2 += r6 ; this forces assignment of ID to r2 681 - * r2 += 1 ; get some fixed off for r2 682 - * r3 += r7 ; this forces assignment of ID to r3 683 - * r3 += 1 ; get some fixed off for r3 684 - */ 685 - BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_6), 686 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 687 - BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_7), 688 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 1), 689 - /* if r6 > r7 goto +1 ; no new information about the state is derived from 690 - * ; this check, thus produced verifier states differ 691 - * ; only in 'insn_idx' 692 - * r2 = r3 ; optionally share ID between r2 and r3 693 - */ 694 - BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_7, 1), 695 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_3), 696 - /* if r3 > ctx->data_end goto exit */ 697 - BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 1), 698 - /* r5 = *(u8 *) (r2 - 1) ; access packet memory using r2, 699 - * ; this is not always safe 700 - */ 701 - BPF_LDX_MEM(BPF_B, BPF_REG_5, BPF_REG_2, -1), 702 - /* exit(0) */ 703 - BPF_MOV64_IMM(BPF_REG_0, 0), 704 - BPF_EXIT_INSN(), 705 - }, 706 - .flags = BPF_F_TEST_STATE_FREQ, 707 - .result = REJECT, 708 - .errstr = "invalid access to packet, off=0 size=1, R2", 709 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 710 - },