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

selftests/bpf: verifier/stack_ptr.c converted to inline assembly

Test verifier/stack_ptr.c automatically converted to use inline assembly.

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

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
edff37b2 f4fe3cfe

+486 -359
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 32 32 #include "verifier_raw_tp_writable.skel.h" 33 33 #include "verifier_ringbuf.skel.h" 34 34 #include "verifier_spill_fill.skel.h" 35 + #include "verifier_stack_ptr.skel.h" 35 36 36 37 __maybe_unused 37 38 static void run_tests_aux(const char *skel_name, skel_elf_bytes_fn elf_bytes_factory) ··· 87 86 void test_verifier_raw_tp_writable(void) { RUN(verifier_raw_tp_writable); } 88 87 void test_verifier_ringbuf(void) { RUN(verifier_ringbuf); } 89 88 void test_verifier_spill_fill(void) { RUN(verifier_spill_fill); } 89 + void test_verifier_stack_ptr(void) { RUN(verifier_stack_ptr); }
+484
tools/testing/selftests/bpf/progs/verifier_stack_ptr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Converted from tools/testing/selftests/bpf/verifier/stack_ptr.c */ 3 + 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <limits.h> 7 + #include "bpf_misc.h" 8 + 9 + #define MAX_ENTRIES 11 10 + 11 + struct test_val { 12 + unsigned int index; 13 + int foo[MAX_ENTRIES]; 14 + }; 15 + 16 + struct { 17 + __uint(type, BPF_MAP_TYPE_ARRAY); 18 + __uint(max_entries, 1); 19 + __type(key, int); 20 + __type(value, struct test_val); 21 + } map_array_48b SEC(".maps"); 22 + 23 + SEC("socket") 24 + __description("PTR_TO_STACK store/load") 25 + __success __success_unpriv __retval(0xfaceb00c) 26 + __naked void ptr_to_stack_store_load(void) 27 + { 28 + asm volatile (" \ 29 + r1 = r10; \ 30 + r1 += -10; \ 31 + r0 = 0xfaceb00c; \ 32 + *(u64*)(r1 + 2) = r0; \ 33 + r0 = *(u64*)(r1 + 2); \ 34 + exit; \ 35 + " ::: __clobber_all); 36 + } 37 + 38 + SEC("socket") 39 + __description("PTR_TO_STACK store/load - bad alignment on off") 40 + __failure __msg("misaligned stack access off (0x0; 0x0)+-8+2 size 8") 41 + __failure_unpriv 42 + __naked void load_bad_alignment_on_off(void) 43 + { 44 + asm volatile (" \ 45 + r1 = r10; \ 46 + r1 += -8; \ 47 + r0 = 0xfaceb00c; \ 48 + *(u64*)(r1 + 2) = r0; \ 49 + r0 = *(u64*)(r1 + 2); \ 50 + exit; \ 51 + " ::: __clobber_all); 52 + } 53 + 54 + SEC("socket") 55 + __description("PTR_TO_STACK store/load - bad alignment on reg") 56 + __failure __msg("misaligned stack access off (0x0; 0x0)+-10+8 size 8") 57 + __failure_unpriv 58 + __naked void load_bad_alignment_on_reg(void) 59 + { 60 + asm volatile (" \ 61 + r1 = r10; \ 62 + r1 += -10; \ 63 + r0 = 0xfaceb00c; \ 64 + *(u64*)(r1 + 8) = r0; \ 65 + r0 = *(u64*)(r1 + 8); \ 66 + exit; \ 67 + " ::: __clobber_all); 68 + } 69 + 70 + SEC("socket") 71 + __description("PTR_TO_STACK store/load - out of bounds low") 72 + __failure __msg("invalid write to stack R1 off=-79992 size=8") 73 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 74 + __naked void load_out_of_bounds_low(void) 75 + { 76 + asm volatile (" \ 77 + r1 = r10; \ 78 + r1 += -80000; \ 79 + r0 = 0xfaceb00c; \ 80 + *(u64*)(r1 + 8) = r0; \ 81 + r0 = *(u64*)(r1 + 8); \ 82 + exit; \ 83 + " ::: __clobber_all); 84 + } 85 + 86 + SEC("socket") 87 + __description("PTR_TO_STACK store/load - out of bounds high") 88 + __failure __msg("invalid write to stack R1 off=0 size=8") 89 + __failure_unpriv 90 + __naked void load_out_of_bounds_high(void) 91 + { 92 + asm volatile (" \ 93 + r1 = r10; \ 94 + r1 += -8; \ 95 + r0 = 0xfaceb00c; \ 96 + *(u64*)(r1 + 8) = r0; \ 97 + r0 = *(u64*)(r1 + 8); \ 98 + exit; \ 99 + " ::: __clobber_all); 100 + } 101 + 102 + SEC("socket") 103 + __description("PTR_TO_STACK check high 1") 104 + __success __success_unpriv __retval(42) 105 + __naked void to_stack_check_high_1(void) 106 + { 107 + asm volatile (" \ 108 + r1 = r10; \ 109 + r1 += -1; \ 110 + r0 = 42; \ 111 + *(u8*)(r1 + 0) = r0; \ 112 + r0 = *(u8*)(r1 + 0); \ 113 + exit; \ 114 + " ::: __clobber_all); 115 + } 116 + 117 + SEC("socket") 118 + __description("PTR_TO_STACK check high 2") 119 + __success __success_unpriv __retval(42) 120 + __naked void to_stack_check_high_2(void) 121 + { 122 + asm volatile (" \ 123 + r1 = r10; \ 124 + r0 = 42; \ 125 + *(u8*)(r1 - 1) = r0; \ 126 + r0 = *(u8*)(r1 - 1); \ 127 + exit; \ 128 + " ::: __clobber_all); 129 + } 130 + 131 + SEC("socket") 132 + __description("PTR_TO_STACK check high 3") 133 + __success __failure_unpriv 134 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 135 + __retval(42) 136 + __naked void to_stack_check_high_3(void) 137 + { 138 + asm volatile (" \ 139 + r1 = r10; \ 140 + r1 += 0; \ 141 + r0 = 42; \ 142 + *(u8*)(r1 - 1) = r0; \ 143 + r0 = *(u8*)(r1 - 1); \ 144 + exit; \ 145 + " ::: __clobber_all); 146 + } 147 + 148 + SEC("socket") 149 + __description("PTR_TO_STACK check high 4") 150 + __failure __msg("invalid write to stack R1 off=0 size=1") 151 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 152 + __naked void to_stack_check_high_4(void) 153 + { 154 + asm volatile (" \ 155 + r1 = r10; \ 156 + r1 += 0; \ 157 + r0 = 42; \ 158 + *(u8*)(r1 + 0) = r0; \ 159 + r0 = *(u8*)(r1 + 0); \ 160 + exit; \ 161 + " ::: __clobber_all); 162 + } 163 + 164 + SEC("socket") 165 + __description("PTR_TO_STACK check high 5") 166 + __failure __msg("invalid write to stack R1") 167 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 168 + __naked void to_stack_check_high_5(void) 169 + { 170 + asm volatile (" \ 171 + r1 = r10; \ 172 + r1 += %[__imm_0]; \ 173 + r0 = 42; \ 174 + *(u8*)(r1 + 0) = r0; \ 175 + r0 = *(u8*)(r1 + 0); \ 176 + exit; \ 177 + " : 178 + : __imm_const(__imm_0, (1 << 29) - 1) 179 + : __clobber_all); 180 + } 181 + 182 + SEC("socket") 183 + __description("PTR_TO_STACK check high 6") 184 + __failure __msg("invalid write to stack") 185 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 186 + __naked void to_stack_check_high_6(void) 187 + { 188 + asm volatile (" \ 189 + r1 = r10; \ 190 + r1 += %[__imm_0]; \ 191 + r0 = 42; \ 192 + *(u8*)(r1 + %[shrt_max]) = r0; \ 193 + r0 = *(u8*)(r1 + %[shrt_max]); \ 194 + exit; \ 195 + " : 196 + : __imm_const(__imm_0, (1 << 29) - 1), 197 + __imm_const(shrt_max, SHRT_MAX) 198 + : __clobber_all); 199 + } 200 + 201 + SEC("socket") 202 + __description("PTR_TO_STACK check high 7") 203 + __failure __msg("fp pointer offset") 204 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 205 + __naked void to_stack_check_high_7(void) 206 + { 207 + asm volatile (" \ 208 + r1 = r10; \ 209 + r1 += %[__imm_0]; \ 210 + r1 += %[__imm_0]; \ 211 + r0 = 42; \ 212 + *(u8*)(r1 + %[shrt_max]) = r0; \ 213 + r0 = *(u8*)(r1 + %[shrt_max]); \ 214 + exit; \ 215 + " : 216 + : __imm_const(__imm_0, (1 << 29) - 1), 217 + __imm_const(shrt_max, SHRT_MAX) 218 + : __clobber_all); 219 + } 220 + 221 + SEC("socket") 222 + __description("PTR_TO_STACK check low 1") 223 + __success __success_unpriv __retval(42) 224 + __naked void to_stack_check_low_1(void) 225 + { 226 + asm volatile (" \ 227 + r1 = r10; \ 228 + r1 += -512; \ 229 + r0 = 42; \ 230 + *(u8*)(r1 + 0) = r0; \ 231 + r0 = *(u8*)(r1 + 0); \ 232 + exit; \ 233 + " ::: __clobber_all); 234 + } 235 + 236 + SEC("socket") 237 + __description("PTR_TO_STACK check low 2") 238 + __success __failure_unpriv 239 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 240 + __retval(42) 241 + __naked void to_stack_check_low_2(void) 242 + { 243 + asm volatile (" \ 244 + r1 = r10; \ 245 + r1 += -513; \ 246 + r0 = 42; \ 247 + *(u8*)(r1 + 1) = r0; \ 248 + r0 = *(u8*)(r1 + 1); \ 249 + exit; \ 250 + " ::: __clobber_all); 251 + } 252 + 253 + SEC("socket") 254 + __description("PTR_TO_STACK check low 3") 255 + __failure __msg("invalid write to stack R1 off=-513 size=1") 256 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 257 + __naked void to_stack_check_low_3(void) 258 + { 259 + asm volatile (" \ 260 + r1 = r10; \ 261 + r1 += -513; \ 262 + r0 = 42; \ 263 + *(u8*)(r1 + 0) = r0; \ 264 + r0 = *(u8*)(r1 + 0); \ 265 + exit; \ 266 + " ::: __clobber_all); 267 + } 268 + 269 + SEC("socket") 270 + __description("PTR_TO_STACK check low 4") 271 + __failure __msg("math between fp pointer") 272 + __failure_unpriv 273 + __naked void to_stack_check_low_4(void) 274 + { 275 + asm volatile (" \ 276 + r1 = r10; \ 277 + r1 += %[int_min]; \ 278 + r0 = 42; \ 279 + *(u8*)(r1 + 0) = r0; \ 280 + r0 = *(u8*)(r1 + 0); \ 281 + exit; \ 282 + " : 283 + : __imm_const(int_min, INT_MIN) 284 + : __clobber_all); 285 + } 286 + 287 + SEC("socket") 288 + __description("PTR_TO_STACK check low 5") 289 + __failure __msg("invalid write to stack") 290 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 291 + __naked void to_stack_check_low_5(void) 292 + { 293 + asm volatile (" \ 294 + r1 = r10; \ 295 + r1 += %[__imm_0]; \ 296 + r0 = 42; \ 297 + *(u8*)(r1 + 0) = r0; \ 298 + r0 = *(u8*)(r1 + 0); \ 299 + exit; \ 300 + " : 301 + : __imm_const(__imm_0, -((1 << 29) - 1)) 302 + : __clobber_all); 303 + } 304 + 305 + SEC("socket") 306 + __description("PTR_TO_STACK check low 6") 307 + __failure __msg("invalid write to stack") 308 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 309 + __naked void to_stack_check_low_6(void) 310 + { 311 + asm volatile (" \ 312 + r1 = r10; \ 313 + r1 += %[__imm_0]; \ 314 + r0 = 42; \ 315 + *(u8*)(r1 %[shrt_min]) = r0; \ 316 + r0 = *(u8*)(r1 %[shrt_min]); \ 317 + exit; \ 318 + " : 319 + : __imm_const(__imm_0, -((1 << 29) - 1)), 320 + __imm_const(shrt_min, SHRT_MIN) 321 + : __clobber_all); 322 + } 323 + 324 + SEC("socket") 325 + __description("PTR_TO_STACK check low 7") 326 + __failure __msg("fp pointer offset") 327 + __msg_unpriv("R1 stack pointer arithmetic goes out of range") 328 + __naked void to_stack_check_low_7(void) 329 + { 330 + asm volatile (" \ 331 + r1 = r10; \ 332 + r1 += %[__imm_0]; \ 333 + r1 += %[__imm_0]; \ 334 + r0 = 42; \ 335 + *(u8*)(r1 %[shrt_min]) = r0; \ 336 + r0 = *(u8*)(r1 %[shrt_min]); \ 337 + exit; \ 338 + " : 339 + : __imm_const(__imm_0, -((1 << 29) - 1)), 340 + __imm_const(shrt_min, SHRT_MIN) 341 + : __clobber_all); 342 + } 343 + 344 + SEC("socket") 345 + __description("PTR_TO_STACK mixed reg/k, 1") 346 + __success __success_unpriv __retval(42) 347 + __naked void stack_mixed_reg_k_1(void) 348 + { 349 + asm volatile (" \ 350 + r1 = r10; \ 351 + r1 += -3; \ 352 + r2 = -3; \ 353 + r1 += r2; \ 354 + r0 = 42; \ 355 + *(u8*)(r1 + 0) = r0; \ 356 + r0 = *(u8*)(r1 + 0); \ 357 + exit; \ 358 + " ::: __clobber_all); 359 + } 360 + 361 + SEC("socket") 362 + __description("PTR_TO_STACK mixed reg/k, 2") 363 + __success __success_unpriv __retval(42) 364 + __naked void stack_mixed_reg_k_2(void) 365 + { 366 + asm volatile (" \ 367 + r0 = 0; \ 368 + *(u64*)(r10 - 8) = r0; \ 369 + r0 = 0; \ 370 + *(u64*)(r10 - 16) = r0; \ 371 + r1 = r10; \ 372 + r1 += -3; \ 373 + r2 = -3; \ 374 + r1 += r2; \ 375 + r0 = 42; \ 376 + *(u8*)(r1 + 0) = r0; \ 377 + r5 = r10; \ 378 + r0 = *(u8*)(r5 - 6); \ 379 + exit; \ 380 + " ::: __clobber_all); 381 + } 382 + 383 + SEC("socket") 384 + __description("PTR_TO_STACK mixed reg/k, 3") 385 + __success __success_unpriv __retval(-3) 386 + __naked void stack_mixed_reg_k_3(void) 387 + { 388 + asm volatile (" \ 389 + r1 = r10; \ 390 + r1 += -3; \ 391 + r2 = -3; \ 392 + r1 += r2; \ 393 + r0 = 42; \ 394 + *(u8*)(r1 + 0) = r0; \ 395 + r0 = r2; \ 396 + exit; \ 397 + " ::: __clobber_all); 398 + } 399 + 400 + SEC("socket") 401 + __description("PTR_TO_STACK reg") 402 + __success __success_unpriv __retval(42) 403 + __naked void ptr_to_stack_reg(void) 404 + { 405 + asm volatile (" \ 406 + r1 = r10; \ 407 + r2 = -3; \ 408 + r1 += r2; \ 409 + r0 = 42; \ 410 + *(u8*)(r1 + 0) = r0; \ 411 + r0 = *(u8*)(r1 + 0); \ 412 + exit; \ 413 + " ::: __clobber_all); 414 + } 415 + 416 + SEC("socket") 417 + __description("stack pointer arithmetic") 418 + __success __success_unpriv __retval(0) 419 + __naked void stack_pointer_arithmetic(void) 420 + { 421 + asm volatile (" \ 422 + r1 = 4; \ 423 + goto l0_%=; \ 424 + l0_%=: r7 = r10; \ 425 + r7 += -10; \ 426 + r7 += -10; \ 427 + r2 = r7; \ 428 + r2 += r1; \ 429 + r0 = 0; \ 430 + *(u32*)(r2 + 4) = r0; \ 431 + r2 = r7; \ 432 + r2 += 8; \ 433 + r0 = 0; \ 434 + *(u32*)(r2 + 4) = r0; \ 435 + r0 = 0; \ 436 + exit; \ 437 + " ::: __clobber_all); 438 + } 439 + 440 + SEC("tc") 441 + __description("store PTR_TO_STACK in R10 to array map using BPF_B") 442 + __success __retval(42) 443 + __naked void array_map_using_bpf_b(void) 444 + { 445 + asm volatile (" \ 446 + /* Load pointer to map. */ \ 447 + r2 = r10; \ 448 + r2 += -8; \ 449 + r1 = 0; \ 450 + *(u64*)(r2 + 0) = r1; \ 451 + r1 = %[map_array_48b] ll; \ 452 + call %[bpf_map_lookup_elem]; \ 453 + if r0 != 0 goto l0_%=; \ 454 + r0 = 2; \ 455 + exit; \ 456 + l0_%=: r1 = r0; \ 457 + /* Copy R10 to R9. */ \ 458 + r9 = r10; \ 459 + /* Pollute other registers with unaligned values. */\ 460 + r2 = -1; \ 461 + r3 = -1; \ 462 + r4 = -1; \ 463 + r5 = -1; \ 464 + r6 = -1; \ 465 + r7 = -1; \ 466 + r8 = -1; \ 467 + /* Store both R9 and R10 with BPF_B and read back. */\ 468 + *(u8*)(r1 + 0) = r10; \ 469 + r2 = *(u8*)(r1 + 0); \ 470 + *(u8*)(r1 + 0) = r9; \ 471 + r3 = *(u8*)(r1 + 0); \ 472 + /* Should read back as same value. */ \ 473 + if r2 == r3 goto l1_%=; \ 474 + r0 = 1; \ 475 + exit; \ 476 + l1_%=: r0 = 42; \ 477 + exit; \ 478 + " : 479 + : __imm(bpf_map_lookup_elem), 480 + __imm_addr(map_array_48b) 481 + : __clobber_all); 482 + } 483 + 484 + char _license[] SEC("license") = "GPL";
-359
tools/testing/selftests/bpf/verifier/stack_ptr.c
··· 1 - { 2 - "PTR_TO_STACK store/load", 3 - .insns = { 4 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 5 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 6 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 7 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 8 - BPF_EXIT_INSN(), 9 - }, 10 - .result = ACCEPT, 11 - .retval = 0xfaceb00c, 12 - }, 13 - { 14 - "PTR_TO_STACK store/load - bad alignment on off", 15 - .insns = { 16 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 17 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 18 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 19 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 20 - BPF_EXIT_INSN(), 21 - }, 22 - .result = REJECT, 23 - .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8", 24 - }, 25 - { 26 - "PTR_TO_STACK store/load - bad alignment on reg", 27 - .insns = { 28 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 29 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 30 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 31 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 32 - BPF_EXIT_INSN(), 33 - }, 34 - .result = REJECT, 35 - .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8", 36 - }, 37 - { 38 - "PTR_TO_STACK store/load - out of bounds low", 39 - .insns = { 40 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 41 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000), 42 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 43 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 44 - BPF_EXIT_INSN(), 45 - }, 46 - .result = REJECT, 47 - .errstr = "invalid write to stack R1 off=-79992 size=8", 48 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 49 - }, 50 - { 51 - "PTR_TO_STACK store/load - out of bounds high", 52 - .insns = { 53 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 54 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 55 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 56 - BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 57 - BPF_EXIT_INSN(), 58 - }, 59 - .result = REJECT, 60 - .errstr = "invalid write to stack R1 off=0 size=8", 61 - }, 62 - { 63 - "PTR_TO_STACK check high 1", 64 - .insns = { 65 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 66 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1), 67 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 68 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 69 - BPF_EXIT_INSN(), 70 - }, 71 - .result = ACCEPT, 72 - .retval = 42, 73 - }, 74 - { 75 - "PTR_TO_STACK check high 2", 76 - .insns = { 77 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 78 - BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42), 79 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1), 80 - BPF_EXIT_INSN(), 81 - }, 82 - .result = ACCEPT, 83 - .retval = 42, 84 - }, 85 - { 86 - "PTR_TO_STACK check high 3", 87 - .insns = { 88 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 89 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), 90 - BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42), 91 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1), 92 - BPF_EXIT_INSN(), 93 - }, 94 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 95 - .result_unpriv = REJECT, 96 - .result = ACCEPT, 97 - .retval = 42, 98 - }, 99 - { 100 - "PTR_TO_STACK check high 4", 101 - .insns = { 102 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 103 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), 104 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 105 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 106 - BPF_EXIT_INSN(), 107 - }, 108 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 109 - .errstr = "invalid write to stack R1 off=0 size=1", 110 - .result = REJECT, 111 - }, 112 - { 113 - "PTR_TO_STACK check high 5", 114 - .insns = { 115 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 116 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 117 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 118 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 119 - BPF_EXIT_INSN(), 120 - }, 121 - .result = REJECT, 122 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 123 - .errstr = "invalid write to stack R1", 124 - }, 125 - { 126 - "PTR_TO_STACK check high 6", 127 - .insns = { 128 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 129 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 130 - BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42), 131 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX), 132 - BPF_EXIT_INSN(), 133 - }, 134 - .result = REJECT, 135 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 136 - .errstr = "invalid write to stack", 137 - }, 138 - { 139 - "PTR_TO_STACK check high 7", 140 - .insns = { 141 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 142 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 143 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 144 - BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42), 145 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX), 146 - BPF_EXIT_INSN(), 147 - }, 148 - .result = REJECT, 149 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 150 - .errstr = "fp pointer offset", 151 - }, 152 - { 153 - "PTR_TO_STACK check low 1", 154 - .insns = { 155 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 156 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -512), 157 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 158 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 159 - BPF_EXIT_INSN(), 160 - }, 161 - .result = ACCEPT, 162 - .retval = 42, 163 - }, 164 - { 165 - "PTR_TO_STACK check low 2", 166 - .insns = { 167 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 168 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513), 169 - BPF_ST_MEM(BPF_B, BPF_REG_1, 1, 42), 170 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 1), 171 - BPF_EXIT_INSN(), 172 - }, 173 - .result_unpriv = REJECT, 174 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 175 - .result = ACCEPT, 176 - .retval = 42, 177 - }, 178 - { 179 - "PTR_TO_STACK check low 3", 180 - .insns = { 181 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 182 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513), 183 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 184 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 185 - BPF_EXIT_INSN(), 186 - }, 187 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 188 - .errstr = "invalid write to stack R1 off=-513 size=1", 189 - .result = REJECT, 190 - }, 191 - { 192 - "PTR_TO_STACK check low 4", 193 - .insns = { 194 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 195 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, INT_MIN), 196 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 197 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 198 - BPF_EXIT_INSN(), 199 - }, 200 - .result = REJECT, 201 - .errstr = "math between fp pointer", 202 - }, 203 - { 204 - "PTR_TO_STACK check low 5", 205 - .insns = { 206 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 207 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 208 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 209 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 210 - BPF_EXIT_INSN(), 211 - }, 212 - .result = REJECT, 213 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 214 - .errstr = "invalid write to stack", 215 - }, 216 - { 217 - "PTR_TO_STACK check low 6", 218 - .insns = { 219 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 220 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 221 - BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42), 222 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN), 223 - BPF_EXIT_INSN(), 224 - }, 225 - .result = REJECT, 226 - .errstr = "invalid write to stack", 227 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 228 - }, 229 - { 230 - "PTR_TO_STACK check low 7", 231 - .insns = { 232 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 233 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 234 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 235 - BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42), 236 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN), 237 - BPF_EXIT_INSN(), 238 - }, 239 - .result = REJECT, 240 - .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 241 - .errstr = "fp pointer offset", 242 - }, 243 - { 244 - "PTR_TO_STACK mixed reg/k, 1", 245 - .insns = { 246 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 247 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 248 - BPF_MOV64_IMM(BPF_REG_2, -3), 249 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 250 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 251 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 252 - BPF_EXIT_INSN(), 253 - }, 254 - .result = ACCEPT, 255 - .retval = 42, 256 - }, 257 - { 258 - "PTR_TO_STACK mixed reg/k, 2", 259 - .insns = { 260 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 261 - BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 262 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 263 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 264 - BPF_MOV64_IMM(BPF_REG_2, -3), 265 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 266 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 267 - BPF_MOV64_REG(BPF_REG_5, BPF_REG_10), 268 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_5, -6), 269 - BPF_EXIT_INSN(), 270 - }, 271 - .result = ACCEPT, 272 - .retval = 42, 273 - }, 274 - { 275 - "PTR_TO_STACK mixed reg/k, 3", 276 - .insns = { 277 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 278 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 279 - BPF_MOV64_IMM(BPF_REG_2, -3), 280 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 281 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 282 - BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 283 - BPF_EXIT_INSN(), 284 - }, 285 - .result = ACCEPT, 286 - .retval = -3, 287 - }, 288 - { 289 - "PTR_TO_STACK reg", 290 - .insns = { 291 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 292 - BPF_MOV64_IMM(BPF_REG_2, -3), 293 - BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 294 - BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 295 - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 296 - BPF_EXIT_INSN(), 297 - }, 298 - .result = ACCEPT, 299 - .retval = 42, 300 - }, 301 - { 302 - "stack pointer arithmetic", 303 - .insns = { 304 - BPF_MOV64_IMM(BPF_REG_1, 4), 305 - BPF_JMP_IMM(BPF_JA, 0, 0, 0), 306 - BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 307 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), 308 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), 309 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 310 - BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1), 311 - BPF_ST_MEM(0, BPF_REG_2, 4, 0), 312 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 313 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 314 - BPF_ST_MEM(0, BPF_REG_2, 4, 0), 315 - BPF_MOV64_IMM(BPF_REG_0, 0), 316 - BPF_EXIT_INSN(), 317 - }, 318 - .result = ACCEPT, 319 - }, 320 - { 321 - "store PTR_TO_STACK in R10 to array map using BPF_B", 322 - .insns = { 323 - /* Load pointer to map. */ 324 - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 325 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 326 - BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), 327 - BPF_LD_MAP_FD(BPF_REG_1, 0), 328 - BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 329 - BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 330 - BPF_MOV64_IMM(BPF_REG_0, 2), 331 - BPF_EXIT_INSN(), 332 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 333 - /* Copy R10 to R9. */ 334 - BPF_MOV64_REG(BPF_REG_9, BPF_REG_10), 335 - /* Pollute other registers with unaligned values. */ 336 - BPF_MOV64_IMM(BPF_REG_2, -1), 337 - BPF_MOV64_IMM(BPF_REG_3, -1), 338 - BPF_MOV64_IMM(BPF_REG_4, -1), 339 - BPF_MOV64_IMM(BPF_REG_5, -1), 340 - BPF_MOV64_IMM(BPF_REG_6, -1), 341 - BPF_MOV64_IMM(BPF_REG_7, -1), 342 - BPF_MOV64_IMM(BPF_REG_8, -1), 343 - /* Store both R9 and R10 with BPF_B and read back. */ 344 - BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, 0), 345 - BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_1, 0), 346 - BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_9, 0), 347 - BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_1, 0), 348 - /* Should read back as same value. */ 349 - BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_3, 2), 350 - BPF_MOV64_IMM(BPF_REG_0, 1), 351 - BPF_EXIT_INSN(), 352 - BPF_MOV64_IMM(BPF_REG_0, 42), 353 - BPF_EXIT_INSN(), 354 - }, 355 - .fixup_map_array_48b = { 3 }, 356 - .result = ACCEPT, 357 - .retval = 42, 358 - .prog_type = BPF_PROG_TYPE_SCHED_CLS, 359 - },