1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/value_ptr_arith.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include <errno.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 struct other_val { 24 long long foo; 25 long long bar; 26 }; 27 28 struct { 29 __uint(type, BPF_MAP_TYPE_HASH); 30 __uint(max_entries, 1); 31 __type(key, long long); 32 __type(value, struct other_val); 33 } map_hash_16b SEC(".maps"); 34 35 struct { 36 __uint(type, BPF_MAP_TYPE_HASH); 37 __uint(max_entries, 1); 38 __type(key, long long); 39 __type(value, struct test_val); 40 } map_hash_48b SEC(".maps"); 41 42 SEC("socket") 43 __description("map access: known scalar += value_ptr unknown vs const") 44 __success __failure_unpriv 45 __msg_unpriv("R1 tried to add from different maps, paths or scalars") 46 __retval(1) 47 __naked void value_ptr_unknown_vs_const(void) 48 { 49 asm volatile (" \ 50 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 51 r1 = 0; \ 52 *(u64*)(r10 - 8) = r1; \ 53 r2 = r10; \ 54 r2 += -8; \ 55 if r0 == 1 goto l0_%=; \ 56 r1 = %[map_hash_16b] ll; \ 57 if r0 != 1 goto l1_%=; \ 58 l0_%=: r1 = %[map_array_48b] ll; \ 59 l1_%=: call %[bpf_map_lookup_elem]; \ 60 if r0 == 0 goto l2_%=; \ 61 r4 = *(u8*)(r0 + 0); \ 62 if r4 == 1 goto l3_%=; \ 63 r1 = 6; \ 64 r1 = -r1; \ 65 r1 &= 0x7; \ 66 goto l4_%=; \ 67 l3_%=: r1 = 3; \ 68 l4_%=: r1 += r0; \ 69 r0 = *(u8*)(r1 + 0); \ 70 l2_%=: r0 = 1; \ 71 exit; \ 72 " : 73 : __imm(bpf_map_lookup_elem), 74 __imm_addr(map_array_48b), 75 __imm_addr(map_hash_16b), 76 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 77 : __clobber_all); 78 } 79 80 SEC("socket") 81 __description("map access: known scalar += value_ptr const vs unknown") 82 __success __failure_unpriv 83 __msg_unpriv("R1 tried to add from different maps, paths or scalars") 84 __retval(1) 85 __naked void value_ptr_const_vs_unknown(void) 86 { 87 asm volatile (" \ 88 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 89 r1 = 0; \ 90 *(u64*)(r10 - 8) = r1; \ 91 r2 = r10; \ 92 r2 += -8; \ 93 if r0 == 1 goto l0_%=; \ 94 r1 = %[map_hash_16b] ll; \ 95 if r0 != 1 goto l1_%=; \ 96 l0_%=: r1 = %[map_array_48b] ll; \ 97 l1_%=: call %[bpf_map_lookup_elem]; \ 98 if r0 == 0 goto l2_%=; \ 99 r4 = *(u8*)(r0 + 0); \ 100 if r4 == 1 goto l3_%=; \ 101 r1 = 3; \ 102 goto l4_%=; \ 103 l3_%=: r1 = 6; \ 104 r1 = -r1; \ 105 r1 &= 0x7; \ 106 l4_%=: r1 += r0; \ 107 r0 = *(u8*)(r1 + 0); \ 108 l2_%=: r0 = 1; \ 109 exit; \ 110 " : 111 : __imm(bpf_map_lookup_elem), 112 __imm_addr(map_array_48b), 113 __imm_addr(map_hash_16b), 114 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 115 : __clobber_all); 116 } 117 118 SEC("socket") 119 __description("map access: known scalar += value_ptr const vs const (ne)") 120 __success __failure_unpriv 121 __msg_unpriv("R1 tried to add from different maps, paths or scalars") 122 __retval(1) 123 __naked void ptr_const_vs_const_ne(void) 124 { 125 asm volatile (" \ 126 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 127 r1 = 0; \ 128 *(u64*)(r10 - 8) = r1; \ 129 r2 = r10; \ 130 r2 += -8; \ 131 if r0 == 1 goto l0_%=; \ 132 r1 = %[map_hash_16b] ll; \ 133 if r0 != 1 goto l1_%=; \ 134 l0_%=: r1 = %[map_array_48b] ll; \ 135 l1_%=: call %[bpf_map_lookup_elem]; \ 136 if r0 == 0 goto l2_%=; \ 137 r4 = *(u8*)(r0 + 0); \ 138 if r4 == 1 goto l3_%=; \ 139 r1 = 3; \ 140 goto l4_%=; \ 141 l3_%=: r1 = 5; \ 142 l4_%=: r1 += r0; \ 143 r0 = *(u8*)(r1 + 0); \ 144 l2_%=: r0 = 1; \ 145 exit; \ 146 " : 147 : __imm(bpf_map_lookup_elem), 148 __imm_addr(map_array_48b), 149 __imm_addr(map_hash_16b), 150 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 151 : __clobber_all); 152 } 153 154 SEC("socket") 155 __description("map access: known scalar += value_ptr const vs const (eq)") 156 __success __success_unpriv __retval(1) 157 __naked void ptr_const_vs_const_eq(void) 158 { 159 asm volatile (" \ 160 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 161 r1 = 0; \ 162 *(u64*)(r10 - 8) = r1; \ 163 r2 = r10; \ 164 r2 += -8; \ 165 if r0 == 1 goto l0_%=; \ 166 r1 = %[map_hash_16b] ll; \ 167 if r0 != 1 goto l1_%=; \ 168 l0_%=: r1 = %[map_array_48b] ll; \ 169 l1_%=: call %[bpf_map_lookup_elem]; \ 170 if r0 == 0 goto l2_%=; \ 171 r4 = *(u8*)(r0 + 0); \ 172 if r4 == 1 goto l3_%=; \ 173 r1 = 5; \ 174 goto l4_%=; \ 175 l3_%=: r1 = 5; \ 176 l4_%=: r1 += r0; \ 177 r0 = *(u8*)(r1 + 0); \ 178 l2_%=: r0 = 1; \ 179 exit; \ 180 " : 181 : __imm(bpf_map_lookup_elem), 182 __imm_addr(map_array_48b), 183 __imm_addr(map_hash_16b), 184 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 185 : __clobber_all); 186 } 187 188 SEC("socket") 189 __description("map access: known scalar += value_ptr unknown vs unknown (eq)") 190 __success __success_unpriv __retval(1) 191 __naked void ptr_unknown_vs_unknown_eq(void) 192 { 193 asm volatile (" \ 194 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 195 r1 = 0; \ 196 *(u64*)(r10 - 8) = r1; \ 197 r2 = r10; \ 198 r2 += -8; \ 199 if r0 == 1 goto l0_%=; \ 200 r1 = %[map_hash_16b] ll; \ 201 if r0 != 1 goto l1_%=; \ 202 l0_%=: r1 = %[map_array_48b] ll; \ 203 l1_%=: call %[bpf_map_lookup_elem]; \ 204 if r0 == 0 goto l2_%=; \ 205 r4 = *(u8*)(r0 + 0); \ 206 if r4 == 1 goto l3_%=; \ 207 r1 = 6; \ 208 r1 = -r1; \ 209 r1 &= 0x7; \ 210 goto l4_%=; \ 211 l3_%=: r1 = 6; \ 212 r1 = -r1; \ 213 r1 &= 0x7; \ 214 l4_%=: r1 += r0; \ 215 r0 = *(u8*)(r1 + 0); \ 216 l2_%=: r0 = 1; \ 217 exit; \ 218 " : 219 : __imm(bpf_map_lookup_elem), 220 __imm_addr(map_array_48b), 221 __imm_addr(map_hash_16b), 222 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 223 : __clobber_all); 224 } 225 226 SEC("socket") 227 __description("map access: known scalar += value_ptr unknown vs unknown (lt)") 228 __success __failure_unpriv 229 __msg_unpriv("R1 tried to add from different maps, paths or scalars") 230 __retval(1) 231 __naked void ptr_unknown_vs_unknown_lt(void) 232 { 233 asm volatile (" \ 234 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 235 r1 = 0; \ 236 *(u64*)(r10 - 8) = r1; \ 237 r2 = r10; \ 238 r2 += -8; \ 239 if r0 == 1 goto l0_%=; \ 240 r1 = %[map_hash_16b] ll; \ 241 if r0 != 1 goto l1_%=; \ 242 l0_%=: r1 = %[map_array_48b] ll; \ 243 l1_%=: call %[bpf_map_lookup_elem]; \ 244 if r0 == 0 goto l2_%=; \ 245 r4 = *(u8*)(r0 + 0); \ 246 if r4 == 1 goto l3_%=; \ 247 r1 = 6; \ 248 r1 = -r1; \ 249 r1 &= 0x3; \ 250 goto l4_%=; \ 251 l3_%=: r1 = 6; \ 252 r1 = -r1; \ 253 r1 &= 0x7; \ 254 l4_%=: r1 += r0; \ 255 r0 = *(u8*)(r1 + 0); \ 256 l2_%=: r0 = 1; \ 257 exit; \ 258 " : 259 : __imm(bpf_map_lookup_elem), 260 __imm_addr(map_array_48b), 261 __imm_addr(map_hash_16b), 262 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 263 : __clobber_all); 264 } 265 266 SEC("socket") 267 __description("map access: known scalar += value_ptr unknown vs unknown (gt)") 268 __success __failure_unpriv 269 __msg_unpriv("R1 tried to add from different maps, paths or scalars") 270 __retval(1) 271 __naked void ptr_unknown_vs_unknown_gt(void) 272 { 273 asm volatile (" \ 274 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 275 r1 = 0; \ 276 *(u64*)(r10 - 8) = r1; \ 277 r2 = r10; \ 278 r2 += -8; \ 279 if r0 == 1 goto l0_%=; \ 280 r1 = %[map_hash_16b] ll; \ 281 if r0 != 1 goto l1_%=; \ 282 l0_%=: r1 = %[map_array_48b] ll; \ 283 l1_%=: call %[bpf_map_lookup_elem]; \ 284 if r0 == 0 goto l2_%=; \ 285 r4 = *(u8*)(r0 + 0); \ 286 if r4 == 1 goto l3_%=; \ 287 r1 = 6; \ 288 r1 = -r1; \ 289 r1 &= 0x7; \ 290 goto l4_%=; \ 291 l3_%=: r1 = 6; \ 292 r1 = -r1; \ 293 r1 &= 0x3; \ 294 l4_%=: r1 += r0; \ 295 r0 = *(u8*)(r1 + 0); \ 296 l2_%=: r0 = 1; \ 297 exit; \ 298 " : 299 : __imm(bpf_map_lookup_elem), 300 __imm_addr(map_array_48b), 301 __imm_addr(map_hash_16b), 302 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 303 : __clobber_all); 304 } 305 306 SEC("socket") 307 __description("map access: known scalar += value_ptr from different maps") 308 __success __success_unpriv __retval(1) 309 __naked void value_ptr_from_different_maps(void) 310 { 311 asm volatile (" \ 312 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 313 r1 = 0; \ 314 *(u64*)(r10 - 8) = r1; \ 315 r2 = r10; \ 316 r2 += -8; \ 317 if r0 == 1 goto l0_%=; \ 318 r1 = %[map_hash_16b] ll; \ 319 if r0 != 1 goto l1_%=; \ 320 l0_%=: r1 = %[map_array_48b] ll; \ 321 l1_%=: call %[bpf_map_lookup_elem]; \ 322 if r0 == 0 goto l2_%=; \ 323 r1 = 4; \ 324 r1 += r0; \ 325 r0 = *(u8*)(r1 + 0); \ 326 l2_%=: r0 = 1; \ 327 exit; \ 328 " : 329 : __imm(bpf_map_lookup_elem), 330 __imm_addr(map_array_48b), 331 __imm_addr(map_hash_16b), 332 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 333 : __clobber_all); 334 } 335 336 SEC("socket") 337 __description("map access: value_ptr -= known scalar from different maps") 338 __success __failure_unpriv 339 __msg_unpriv("R0 min value is outside of the allowed memory range") 340 __retval(1) 341 __naked void known_scalar_from_different_maps(void) 342 { 343 asm volatile (" \ 344 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 345 r1 = 0; \ 346 *(u64*)(r10 - 8) = r1; \ 347 r2 = r10; \ 348 r2 += -8; \ 349 if r0 == 1 goto l0_%=; \ 350 r1 = %[map_hash_16b] ll; \ 351 if r0 != 1 goto l1_%=; \ 352 l0_%=: r1 = %[map_array_48b] ll; \ 353 l1_%=: call %[bpf_map_lookup_elem]; \ 354 if r0 == 0 goto l2_%=; \ 355 r1 = 4; \ 356 r0 -= r1; \ 357 r0 += r1; \ 358 r0 = *(u8*)(r0 + 0); \ 359 l2_%=: r0 = 1; \ 360 exit; \ 361 " : 362 : __imm(bpf_map_lookup_elem), 363 __imm_addr(map_array_48b), 364 __imm_addr(map_hash_16b), 365 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 366 : __clobber_all); 367 } 368 369 SEC("socket") 370 __description("map access: known scalar += value_ptr from different maps, but same value properties") 371 __success __success_unpriv __retval(1) 372 __naked void maps_but_same_value_properties(void) 373 { 374 asm volatile (" \ 375 r0 = *(u32*)(r1 + %[__sk_buff_len]); \ 376 r1 = 0; \ 377 *(u64*)(r10 - 8) = r1; \ 378 r2 = r10; \ 379 r2 += -8; \ 380 if r0 == 1 goto l0_%=; \ 381 r1 = %[map_hash_48b] ll; \ 382 if r0 != 1 goto l1_%=; \ 383 l0_%=: r1 = %[map_array_48b] ll; \ 384 l1_%=: call %[bpf_map_lookup_elem]; \ 385 if r0 == 0 goto l2_%=; \ 386 r1 = 4; \ 387 r1 += r0; \ 388 r0 = *(u8*)(r1 + 0); \ 389 l2_%=: r0 = 1; \ 390 exit; \ 391 " : 392 : __imm(bpf_map_lookup_elem), 393 __imm_addr(map_array_48b), 394 __imm_addr(map_hash_48b), 395 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len)) 396 : __clobber_all); 397 } 398 399 SEC("socket") 400 __description("map access: mixing value pointer and scalar, 1") 401 __success __failure_unpriv 402 __msg_unpriv("R2 tried to add from different maps, paths or scalars, pointer arithmetic with it prohibited for !root") 403 __retval(0) 404 __naked void value_pointer_and_scalar_1(void) 405 { 406 asm volatile (" \ 407 /* load map value pointer into r0 and r2 */ \ 408 r0 = 1; \ 409 r1 = %[map_array_48b] ll; \ 410 r2 = r10; \ 411 r2 += -16; \ 412 r6 = 0; \ 413 *(u64*)(r10 - 16) = r6; \ 414 call %[bpf_map_lookup_elem]; \ 415 if r0 != 0 goto l0_%=; \ 416 exit; \ 417 l0_%=: /* load some number from the map into r1 */ \ 418 r1 = *(u8*)(r0 + 0); \ 419 /* depending on r1, branch: */ \ 420 if r1 != 0 goto l1_%=; \ 421 /* branch A */ \ 422 r2 = r0; \ 423 r3 = 0; \ 424 goto l2_%=; \ 425 l1_%=: /* branch B */ \ 426 r2 = 0; \ 427 r3 = 0x100000; \ 428 l2_%=: /* common instruction */ \ 429 r2 += r3; \ 430 /* depending on r1, branch: */ \ 431 if r1 != 0 goto l3_%=; \ 432 /* branch A */ \ 433 goto l4_%=; \ 434 l3_%=: /* branch B */ \ 435 r0 = 0x13371337; \ 436 /* verifier follows fall-through */ \ 437 /* unpriv: nospec (inserted to prevent `R2 pointer comparison prohibited`) */\ 438 if r2 != 0x100000 goto l4_%=; \ 439 r0 = 0; \ 440 exit; \ 441 l4_%=: /* fake-dead code; targeted from branch A to \ 442 * prevent dead code sanitization \ 443 */ \ 444 r0 = *(u8*)(r0 + 0); \ 445 r0 = 0; \ 446 exit; \ 447 " : 448 : __imm(bpf_map_lookup_elem), 449 __imm_addr(map_array_48b) 450 : __clobber_all); 451 } 452 453 SEC("socket") 454 __description("map access: mixing value pointer and scalar, 2") 455 __success __failure_unpriv 456 __msg_unpriv("R2 tried to add from different maps, paths or scalars, pointer arithmetic with it prohibited for !root") 457 __retval(0) 458 __naked void value_pointer_and_scalar_2(void) 459 { 460 asm volatile (" \ 461 /* load map value pointer into r0 and r2 */ \ 462 r0 = 1; \ 463 r1 = %[map_array_48b] ll; \ 464 r2 = r10; \ 465 r2 += -16; \ 466 r6 = 0; \ 467 *(u64*)(r10 - 16) = r6; \ 468 call %[bpf_map_lookup_elem]; \ 469 if r0 != 0 goto l0_%=; \ 470 exit; \ 471 l0_%=: /* load some number from the map into r1 */ \ 472 r1 = *(u8*)(r0 + 0); \ 473 /* depending on r1, branch: */ \ 474 if r1 == 0 goto l1_%=; \ 475 /* branch A */ \ 476 r2 = 0; \ 477 r3 = 0x100000; \ 478 goto l2_%=; \ 479 l1_%=: /* branch B */ \ 480 r2 = r0; \ 481 r3 = 0; \ 482 l2_%=: /* common instruction */ \ 483 r2 += r3; \ 484 /* depending on r1, branch: */ \ 485 if r1 != 0 goto l3_%=; \ 486 /* branch A */ \ 487 goto l4_%=; \ 488 l3_%=: /* branch B */ \ 489 r0 = 0x13371337; \ 490 /* verifier follows fall-through */ \ 491 if r2 != 0x100000 goto l4_%=; \ 492 r0 = 0; \ 493 exit; \ 494 l4_%=: /* fake-dead code; targeted from branch A to \ 495 * prevent dead code sanitization, rejected \ 496 * via branch B however \ 497 */ \ 498 /* unpriv: nospec (inserted to prevent `R0 invalid mem access 'scalar'`) */\ 499 r0 = *(u8*)(r0 + 0); \ 500 r0 = 0; \ 501 exit; \ 502 " : 503 : __imm(bpf_map_lookup_elem), 504 __imm_addr(map_array_48b) 505 : __clobber_all); 506 } 507 508 SEC("socket") 509 __description("sanitation: alu with different scalars 1") 510 __success __success_unpriv __retval(0x100000) 511 __naked void alu_with_different_scalars_1(void) 512 { 513 asm volatile (" \ 514 r0 = 1; \ 515 r1 = %[map_array_48b] ll; \ 516 r2 = r10; \ 517 r2 += -16; \ 518 r6 = 0; \ 519 *(u64*)(r10 - 16) = r6; \ 520 call %[bpf_map_lookup_elem]; \ 521 if r0 != 0 goto l0_%=; \ 522 exit; \ 523 l0_%=: r1 = *(u32*)(r0 + 0); \ 524 if r1 == 0 goto l1_%=; \ 525 r2 = 0; \ 526 r3 = 0x100000; \ 527 goto l2_%=; \ 528 l1_%=: r2 = 42; \ 529 r3 = 0x100001; \ 530 l2_%=: r2 += r3; \ 531 r0 = r2; \ 532 exit; \ 533 " : 534 : __imm(bpf_map_lookup_elem), 535 __imm_addr(map_array_48b) 536 : __clobber_all); 537 } 538 539 SEC("socket") 540 __description("sanitation: alu with different scalars 2") 541 __success __success_unpriv __retval(0) 542 __naked void alu_with_different_scalars_2(void) 543 { 544 asm volatile (" \ 545 r0 = 1; \ 546 r1 = %[map_array_48b] ll; \ 547 r6 = r1; \ 548 r2 = r10; \ 549 r2 += -16; \ 550 r7 = 0; \ 551 *(u64*)(r10 - 16) = r7; \ 552 call %[bpf_map_delete_elem]; \ 553 r7 = r0; \ 554 r1 = r6; \ 555 r2 = r10; \ 556 r2 += -16; \ 557 call %[bpf_map_delete_elem]; \ 558 r6 = r0; \ 559 r8 = r6; \ 560 r8 += r7; \ 561 r0 = r8; \ 562 r0 += %[einval]; \ 563 r0 += %[einval]; \ 564 exit; \ 565 " : 566 : __imm(bpf_map_delete_elem), 567 __imm_addr(map_array_48b), 568 __imm_const(einval, EINVAL) 569 : __clobber_all); 570 } 571 572 SEC("socket") 573 __description("sanitation: alu with different scalars 3") 574 __success __success_unpriv __retval(0) 575 __naked void alu_with_different_scalars_3(void) 576 { 577 asm volatile (" \ 578 r0 = %[einval]; \ 579 r0 *= -1; \ 580 r7 = r0; \ 581 r0 = %[einval]; \ 582 r0 *= -1; \ 583 r6 = r0; \ 584 r8 = r6; \ 585 r8 += r7; \ 586 r0 = r8; \ 587 r0 += %[einval]; \ 588 r0 += %[einval]; \ 589 exit; \ 590 " : 591 : __imm_const(einval, EINVAL) 592 : __clobber_all); 593 } 594 595 SEC("socket") 596 __description("map access: value_ptr += known scalar, upper oob arith, test 1") 597 __success __failure_unpriv 598 __msg_unpriv("R0 pointer arithmetic of map value goes out of range") 599 __retval(1) 600 __naked void upper_oob_arith_test_1(void) 601 { 602 asm volatile (" \ 603 r1 = 0; \ 604 *(u64*)(r10 - 8) = r1; \ 605 r2 = r10; \ 606 r2 += -8; \ 607 r1 = %[map_array_48b] ll; \ 608 call %[bpf_map_lookup_elem]; \ 609 if r0 == 0 goto l0_%=; \ 610 r1 = 48; \ 611 r0 += r1; \ 612 r0 -= r1; \ 613 r0 = *(u8*)(r0 + 0); \ 614 l0_%=: r0 = 1; \ 615 exit; \ 616 " : 617 : __imm(bpf_map_lookup_elem), 618 __imm_addr(map_array_48b) 619 : __clobber_all); 620 } 621 622 SEC("socket") 623 __description("map access: value_ptr += known scalar, upper oob arith, test 2") 624 __success __failure_unpriv 625 __msg_unpriv("R0 pointer arithmetic of map value goes out of range") 626 __retval(1) 627 __naked void upper_oob_arith_test_2(void) 628 { 629 asm volatile (" \ 630 r1 = 0; \ 631 *(u64*)(r10 - 8) = r1; \ 632 r2 = r10; \ 633 r2 += -8; \ 634 r1 = %[map_array_48b] ll; \ 635 call %[bpf_map_lookup_elem]; \ 636 if r0 == 0 goto l0_%=; \ 637 r1 = 49; \ 638 r0 += r1; \ 639 r0 -= r1; \ 640 r0 = *(u8*)(r0 + 0); \ 641 l0_%=: r0 = 1; \ 642 exit; \ 643 " : 644 : __imm(bpf_map_lookup_elem), 645 __imm_addr(map_array_48b) 646 : __clobber_all); 647 } 648 649 SEC("socket") 650 __description("map access: value_ptr += known scalar, upper oob arith, test 3") 651 __success __success_unpriv __retval(1) 652 __naked void upper_oob_arith_test_3(void) 653 { 654 asm volatile (" \ 655 r1 = 0; \ 656 *(u64*)(r10 - 8) = r1; \ 657 r2 = r10; \ 658 r2 += -8; \ 659 r1 = %[map_array_48b] ll; \ 660 call %[bpf_map_lookup_elem]; \ 661 if r0 == 0 goto l0_%=; \ 662 r1 = 47; \ 663 r0 += r1; \ 664 r0 -= r1; \ 665 r0 = *(u8*)(r0 + 0); \ 666 l0_%=: r0 = 1; \ 667 exit; \ 668 " : 669 : __imm(bpf_map_lookup_elem), 670 __imm_addr(map_array_48b) 671 : __clobber_all); 672 } 673 674 SEC("socket") 675 __description("map access: value_ptr -= known scalar, lower oob arith, test 1") 676 __failure __msg("R0 min value is outside of the allowed memory range") 677 __failure_unpriv 678 __msg_unpriv("R0 pointer arithmetic of map value goes out of range") 679 __naked void lower_oob_arith_test_1(void) 680 { 681 asm volatile (" \ 682 r1 = 0; \ 683 *(u64*)(r10 - 8) = r1; \ 684 r2 = r10; \ 685 r2 += -8; \ 686 r1 = %[map_array_48b] ll; \ 687 call %[bpf_map_lookup_elem]; \ 688 if r0 == 0 goto l0_%=; \ 689 r1 = 47; \ 690 r0 += r1; \ 691 r1 = 48; \ 692 r0 -= r1; \ 693 r0 = *(u8*)(r0 + 0); \ 694 l0_%=: r0 = 1; \ 695 exit; \ 696 " : 697 : __imm(bpf_map_lookup_elem), 698 __imm_addr(map_array_48b) 699 : __clobber_all); 700 } 701 702 SEC("socket") 703 __description("map access: value_ptr -= known scalar, lower oob arith, test 2") 704 __success __failure_unpriv 705 __msg_unpriv("R0 pointer arithmetic of map value goes out of range") 706 __retval(1) 707 __naked void lower_oob_arith_test_2(void) 708 { 709 asm volatile (" \ 710 r1 = 0; \ 711 *(u64*)(r10 - 8) = r1; \ 712 r2 = r10; \ 713 r2 += -8; \ 714 r1 = %[map_array_48b] ll; \ 715 call %[bpf_map_lookup_elem]; \ 716 if r0 == 0 goto l0_%=; \ 717 r1 = 47; \ 718 r0 += r1; \ 719 r1 = 48; \ 720 r0 -= r1; \ 721 r1 = 1; \ 722 r0 += r1; \ 723 r0 = *(u8*)(r0 + 0); \ 724 l0_%=: r0 = 1; \ 725 exit; \ 726 " : 727 : __imm(bpf_map_lookup_elem), 728 __imm_addr(map_array_48b) 729 : __clobber_all); 730 } 731 732 SEC("socket") 733 __description("map access: value_ptr -= known scalar, lower oob arith, test 3") 734 __success __success_unpriv __retval(1) 735 __naked void lower_oob_arith_test_3(void) 736 { 737 asm volatile (" \ 738 r1 = 0; \ 739 *(u64*)(r10 - 8) = r1; \ 740 r2 = r10; \ 741 r2 += -8; \ 742 r1 = %[map_array_48b] ll; \ 743 call %[bpf_map_lookup_elem]; \ 744 if r0 == 0 goto l0_%=; \ 745 r1 = 47; \ 746 r0 += r1; \ 747 r1 = 47; \ 748 r0 -= r1; \ 749 r0 = *(u8*)(r0 + 0); \ 750 l0_%=: r0 = 1; \ 751 exit; \ 752 " : 753 : __imm(bpf_map_lookup_elem), 754 __imm_addr(map_array_48b) 755 : __clobber_all); 756 } 757 758 SEC("socket") 759 __description("map access: known scalar += value_ptr") 760 __success __success_unpriv __retval(1) 761 __naked void access_known_scalar_value_ptr_1(void) 762 { 763 asm volatile (" \ 764 r1 = 0; \ 765 *(u64*)(r10 - 8) = r1; \ 766 r2 = r10; \ 767 r2 += -8; \ 768 r1 = %[map_array_48b] ll; \ 769 call %[bpf_map_lookup_elem]; \ 770 if r0 == 0 goto l0_%=; \ 771 r1 = 4; \ 772 r1 += r0; \ 773 r0 = *(u8*)(r1 + 0); \ 774 l0_%=: r0 = 1; \ 775 exit; \ 776 " : 777 : __imm(bpf_map_lookup_elem), 778 __imm_addr(map_array_48b) 779 : __clobber_all); 780 } 781 782 SEC("socket") 783 __description("map access: value_ptr += known scalar, 1") 784 __success __success_unpriv __retval(1) 785 __naked void value_ptr_known_scalar_1(void) 786 { 787 asm volatile (" \ 788 r1 = 0; \ 789 *(u64*)(r10 - 8) = r1; \ 790 r2 = r10; \ 791 r2 += -8; \ 792 r1 = %[map_array_48b] ll; \ 793 call %[bpf_map_lookup_elem]; \ 794 if r0 == 0 goto l0_%=; \ 795 r1 = 4; \ 796 r0 += r1; \ 797 r1 = *(u8*)(r0 + 0); \ 798 l0_%=: r0 = 1; \ 799 exit; \ 800 " : 801 : __imm(bpf_map_lookup_elem), 802 __imm_addr(map_array_48b) 803 : __clobber_all); 804 } 805 806 SEC("socket") 807 __description("map access: value_ptr += known scalar, 2") 808 __failure __msg("invalid access to map value") 809 __failure_unpriv 810 __naked void value_ptr_known_scalar_2_1(void) 811 { 812 asm volatile (" \ 813 r1 = 0; \ 814 *(u64*)(r10 - 8) = r1; \ 815 r2 = r10; \ 816 r2 += -8; \ 817 r1 = %[map_array_48b] ll; \ 818 call %[bpf_map_lookup_elem]; \ 819 if r0 == 0 goto l0_%=; \ 820 r1 = 49; \ 821 r0 += r1; \ 822 r1 = *(u8*)(r0 + 0); \ 823 l0_%=: r0 = 1; \ 824 exit; \ 825 " : 826 : __imm(bpf_map_lookup_elem), 827 __imm_addr(map_array_48b) 828 : __clobber_all); 829 } 830 831 SEC("socket") 832 __description("map access: value_ptr += known scalar, 3") 833 __failure __msg("invalid access to map value") 834 __failure_unpriv 835 __naked void value_ptr_known_scalar_3(void) 836 { 837 asm volatile (" \ 838 r1 = 0; \ 839 *(u64*)(r10 - 8) = r1; \ 840 r2 = r10; \ 841 r2 += -8; \ 842 r1 = %[map_array_48b] ll; \ 843 call %[bpf_map_lookup_elem]; \ 844 if r0 == 0 goto l0_%=; \ 845 r1 = -1; \ 846 r0 += r1; \ 847 r1 = *(u8*)(r0 + 0); \ 848 l0_%=: r0 = 1; \ 849 exit; \ 850 " : 851 : __imm(bpf_map_lookup_elem), 852 __imm_addr(map_array_48b) 853 : __clobber_all); 854 } 855 856 SEC("socket") 857 __description("map access: value_ptr += known scalar, 4") 858 __success __success_unpriv __retval(1) 859 __naked void value_ptr_known_scalar_4(void) 860 { 861 asm volatile (" \ 862 r1 = 0; \ 863 *(u64*)(r10 - 8) = r1; \ 864 r2 = r10; \ 865 r2 += -8; \ 866 r1 = %[map_array_48b] ll; \ 867 call %[bpf_map_lookup_elem]; \ 868 if r0 == 0 goto l0_%=; \ 869 r1 = 5; \ 870 r0 += r1; \ 871 r1 = -2; \ 872 r0 += r1; \ 873 r1 = -1; \ 874 r0 += r1; \ 875 r1 = *(u8*)(r0 + 0); \ 876 l0_%=: r0 = 1; \ 877 exit; \ 878 " : 879 : __imm(bpf_map_lookup_elem), 880 __imm_addr(map_array_48b) 881 : __clobber_all); 882 } 883 884 SEC("socket") 885 __description("map access: value_ptr += known scalar, 5") 886 __success __success_unpriv __retval(0xabcdef12) 887 __naked void value_ptr_known_scalar_5(void) 888 { 889 asm volatile (" \ 890 r1 = 0; \ 891 *(u64*)(r10 - 8) = r1; \ 892 r2 = r10; \ 893 r2 += -8; \ 894 r1 = %[map_array_48b] ll; \ 895 call %[bpf_map_lookup_elem]; \ 896 if r0 == 0 goto l0_%=; \ 897 r1 = %[__imm_0]; \ 898 r1 += r0; \ 899 r0 = *(u32*)(r1 + 0); \ 900 l0_%=: exit; \ 901 " : 902 : __imm(bpf_map_lookup_elem), 903 __imm_addr(map_array_48b), 904 __imm_const(__imm_0, (6 + 1) * sizeof(int)) 905 : __clobber_all); 906 } 907 908 SEC("socket") 909 __description("map access: value_ptr += known scalar, 6") 910 __success __success_unpriv __retval(0xabcdef12) 911 __naked void value_ptr_known_scalar_6(void) 912 { 913 asm volatile (" \ 914 r1 = 0; \ 915 *(u64*)(r10 - 8) = r1; \ 916 r2 = r10; \ 917 r2 += -8; \ 918 r1 = %[map_array_48b] ll; \ 919 call %[bpf_map_lookup_elem]; \ 920 if r0 == 0 goto l0_%=; \ 921 r1 = %[__imm_0]; \ 922 r0 += r1; \ 923 r1 = %[__imm_1]; \ 924 r0 += r1; \ 925 r0 = *(u32*)(r0 + 0); \ 926 l0_%=: exit; \ 927 " : 928 : __imm(bpf_map_lookup_elem), 929 __imm_addr(map_array_48b), 930 __imm_const(__imm_0, (3 + 1) * sizeof(int)), 931 __imm_const(__imm_1, 3 * sizeof(int)) 932 : __clobber_all); 933 } 934 935 SEC("socket") 936 __description("map access: value_ptr += N, value_ptr -= N known scalar") 937 __success __success_unpriv __retval(0x12345678) 938 __naked void value_ptr_n_known_scalar(void) 939 { 940 asm volatile (" \ 941 r1 = 0; \ 942 *(u64*)(r10 - 8) = r1; \ 943 r2 = r10; \ 944 r2 += -8; \ 945 r1 = %[map_array_48b] ll; \ 946 call %[bpf_map_lookup_elem]; \ 947 if r0 == 0 goto l0_%=; \ 948 w1 = 0x12345678; \ 949 *(u32*)(r0 + 0) = r1; \ 950 r0 += 2; \ 951 r1 = 2; \ 952 r0 -= r1; \ 953 r0 = *(u32*)(r0 + 0); \ 954 l0_%=: exit; \ 955 " : 956 : __imm(bpf_map_lookup_elem), 957 __imm_addr(map_array_48b) 958 : __clobber_all); 959 } 960 961 SEC("socket") 962 __description("map access: unknown scalar += value_ptr, 1") 963 __success __success_unpriv __retval(1) 964 __naked void unknown_scalar_value_ptr_1(void) 965 { 966 asm volatile (" \ 967 r1 = 0; \ 968 *(u64*)(r10 - 8) = r1; \ 969 r2 = r10; \ 970 r2 += -8; \ 971 r1 = %[map_array_48b] ll; \ 972 call %[bpf_map_lookup_elem]; \ 973 if r0 == 0 goto l0_%=; \ 974 r1 = *(u8*)(r0 + 0); \ 975 r1 &= 0xf; \ 976 r1 += r0; \ 977 r0 = *(u8*)(r1 + 0); \ 978 l0_%=: r0 = 1; \ 979 exit; \ 980 " : 981 : __imm(bpf_map_lookup_elem), 982 __imm_addr(map_array_48b) 983 : __clobber_all); 984 } 985 986 SEC("socket") 987 __description("map access: unknown scalar += value_ptr, 2") 988 __success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 989 __naked void unknown_scalar_value_ptr_2(void) 990 { 991 asm volatile (" \ 992 r1 = 0; \ 993 *(u64*)(r10 - 8) = r1; \ 994 r2 = r10; \ 995 r2 += -8; \ 996 r1 = %[map_array_48b] ll; \ 997 call %[bpf_map_lookup_elem]; \ 998 if r0 == 0 goto l0_%=; \ 999 r1 = *(u32*)(r0 + 0); \ 1000 r1 &= 31; \ 1001 r1 += r0; \ 1002 r0 = *(u32*)(r1 + 0); \ 1003 l0_%=: exit; \ 1004 " : 1005 : __imm(bpf_map_lookup_elem), 1006 __imm_addr(map_array_48b) 1007 : __clobber_all); 1008 } 1009 1010 SEC("socket") 1011 __description("map access: unknown scalar += value_ptr, 3") 1012 __success __failure_unpriv 1013 __msg_unpriv("R0 pointer arithmetic of map value goes out of range") 1014 __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 1015 __naked void unknown_scalar_value_ptr_3(void) 1016 { 1017 asm volatile (" \ 1018 r1 = 0; \ 1019 *(u64*)(r10 - 8) = r1; \ 1020 r2 = r10; \ 1021 r2 += -8; \ 1022 r1 = %[map_array_48b] ll; \ 1023 call %[bpf_map_lookup_elem]; \ 1024 if r0 == 0 goto l0_%=; \ 1025 r1 = -1; \ 1026 r0 += r1; \ 1027 r1 = 1; \ 1028 r0 += r1; \ 1029 r1 = *(u32*)(r0 + 0); \ 1030 r1 &= 31; \ 1031 r1 += r0; \ 1032 r0 = *(u32*)(r1 + 0); \ 1033 l0_%=: exit; \ 1034 " : 1035 : __imm(bpf_map_lookup_elem), 1036 __imm_addr(map_array_48b) 1037 : __clobber_all); 1038 } 1039 1040 SEC("socket") 1041 __description("map access: unknown scalar += value_ptr, 4") 1042 __failure __msg("R1 max value is outside of the allowed memory range") 1043 __msg_unpriv("R1 pointer arithmetic of map value goes out of range") 1044 __flag(BPF_F_ANY_ALIGNMENT) 1045 __naked void unknown_scalar_value_ptr_4(void) 1046 { 1047 asm volatile (" \ 1048 r1 = 0; \ 1049 *(u64*)(r10 - 8) = r1; \ 1050 r2 = r10; \ 1051 r2 += -8; \ 1052 r1 = %[map_array_48b] ll; \ 1053 call %[bpf_map_lookup_elem]; \ 1054 if r0 == 0 goto l0_%=; \ 1055 r1 = 19; \ 1056 r0 += r1; \ 1057 r1 = *(u32*)(r0 + 0); \ 1058 r1 &= 31; \ 1059 r1 += r0; \ 1060 r0 = *(u32*)(r1 + 0); \ 1061 l0_%=: exit; \ 1062 " : 1063 : __imm(bpf_map_lookup_elem), 1064 __imm_addr(map_array_48b) 1065 : __clobber_all); 1066 } 1067 1068 SEC("socket") 1069 __description("map access: value_ptr += unknown scalar, 1") 1070 __success __success_unpriv __retval(1) 1071 __naked void value_ptr_unknown_scalar_1(void) 1072 { 1073 asm volatile (" \ 1074 r1 = 0; \ 1075 *(u64*)(r10 - 8) = r1; \ 1076 r2 = r10; \ 1077 r2 += -8; \ 1078 r1 = %[map_array_48b] ll; \ 1079 call %[bpf_map_lookup_elem]; \ 1080 if r0 == 0 goto l0_%=; \ 1081 r1 = *(u8*)(r0 + 0); \ 1082 r1 &= 0xf; \ 1083 r0 += r1; \ 1084 r1 = *(u8*)(r0 + 0); \ 1085 l0_%=: r0 = 1; \ 1086 exit; \ 1087 " : 1088 : __imm(bpf_map_lookup_elem), 1089 __imm_addr(map_array_48b) 1090 : __clobber_all); 1091 } 1092 1093 SEC("socket") 1094 __description("map access: value_ptr += unknown scalar, 2") 1095 __success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 1096 __naked void value_ptr_unknown_scalar_2_1(void) 1097 { 1098 asm volatile (" \ 1099 r1 = 0; \ 1100 *(u64*)(r10 - 8) = r1; \ 1101 r2 = r10; \ 1102 r2 += -8; \ 1103 r1 = %[map_array_48b] ll; \ 1104 call %[bpf_map_lookup_elem]; \ 1105 if r0 == 0 goto l0_%=; \ 1106 r1 = *(u32*)(r0 + 0); \ 1107 r1 &= 31; \ 1108 r0 += r1; \ 1109 r0 = *(u32*)(r0 + 0); \ 1110 l0_%=: exit; \ 1111 " : 1112 : __imm(bpf_map_lookup_elem), 1113 __imm_addr(map_array_48b) 1114 : __clobber_all); 1115 } 1116 1117 SEC("socket") 1118 __description("map access: value_ptr += unknown scalar, 3") 1119 __success __success_unpriv __retval(1) 1120 __naked void value_ptr_unknown_scalar_3(void) 1121 { 1122 asm volatile (" \ 1123 r1 = 0; \ 1124 *(u64*)(r10 - 8) = r1; \ 1125 r2 = r10; \ 1126 r2 += -8; \ 1127 r1 = %[map_array_48b] ll; \ 1128 call %[bpf_map_lookup_elem]; \ 1129 if r0 == 0 goto l0_%=; \ 1130 r1 = *(u64*)(r0 + 0); \ 1131 r2 = *(u64*)(r0 + 8); \ 1132 r3 = *(u64*)(r0 + 16); \ 1133 r1 &= 0xf; \ 1134 r3 &= 1; \ 1135 r3 |= 1; \ 1136 if r2 > r3 goto l0_%=; \ 1137 r0 += r3; \ 1138 r0 = *(u8*)(r0 + 0); \ 1139 r0 = 1; \ 1140 l1_%=: exit; \ 1141 l0_%=: r0 = 2; \ 1142 goto l1_%=; \ 1143 " : 1144 : __imm(bpf_map_lookup_elem), 1145 __imm_addr(map_array_48b) 1146 : __clobber_all); 1147 } 1148 1149 SEC("socket") 1150 __description("map access: value_ptr += value_ptr") 1151 __failure __msg("R0 pointer += pointer prohibited") 1152 __failure_unpriv 1153 __naked void access_value_ptr_value_ptr_1(void) 1154 { 1155 asm volatile (" \ 1156 r1 = 0; \ 1157 *(u64*)(r10 - 8) = r1; \ 1158 r2 = r10; \ 1159 r2 += -8; \ 1160 r1 = %[map_array_48b] ll; \ 1161 call %[bpf_map_lookup_elem]; \ 1162 if r0 == 0 goto l0_%=; \ 1163 r0 += r0; \ 1164 r1 = *(u8*)(r0 + 0); \ 1165 l0_%=: r0 = 1; \ 1166 exit; \ 1167 " : 1168 : __imm(bpf_map_lookup_elem), 1169 __imm_addr(map_array_48b) 1170 : __clobber_all); 1171 } 1172 1173 SEC("socket") 1174 __description("map access: known scalar -= value_ptr") 1175 __failure __msg("R1 tried to subtract pointer from scalar") 1176 __failure_unpriv 1177 __naked void access_known_scalar_value_ptr_2(void) 1178 { 1179 asm volatile (" \ 1180 r1 = 0; \ 1181 *(u64*)(r10 - 8) = r1; \ 1182 r2 = r10; \ 1183 r2 += -8; \ 1184 r1 = %[map_array_48b] ll; \ 1185 call %[bpf_map_lookup_elem]; \ 1186 if r0 == 0 goto l0_%=; \ 1187 r1 = 4; \ 1188 r1 -= r0; \ 1189 r0 = *(u8*)(r1 + 0); \ 1190 l0_%=: r0 = 1; \ 1191 exit; \ 1192 " : 1193 : __imm(bpf_map_lookup_elem), 1194 __imm_addr(map_array_48b) 1195 : __clobber_all); 1196 } 1197 1198 SEC("socket") 1199 __description("map access: value_ptr -= known scalar") 1200 __failure __msg("R0 min value is outside of the allowed memory range") 1201 __failure_unpriv 1202 __naked void access_value_ptr_known_scalar(void) 1203 { 1204 asm volatile (" \ 1205 r1 = 0; \ 1206 *(u64*)(r10 - 8) = r1; \ 1207 r2 = r10; \ 1208 r2 += -8; \ 1209 r1 = %[map_array_48b] ll; \ 1210 call %[bpf_map_lookup_elem]; \ 1211 if r0 == 0 goto l0_%=; \ 1212 r1 = 4; \ 1213 r0 -= r1; \ 1214 r1 = *(u8*)(r0 + 0); \ 1215 l0_%=: r0 = 1; \ 1216 exit; \ 1217 " : 1218 : __imm(bpf_map_lookup_elem), 1219 __imm_addr(map_array_48b) 1220 : __clobber_all); 1221 } 1222 1223 SEC("socket") 1224 __description("map access: value_ptr -= known scalar, 2") 1225 __success __success_unpriv __retval(1) 1226 __naked void value_ptr_known_scalar_2_2(void) 1227 { 1228 asm volatile (" \ 1229 r1 = 0; \ 1230 *(u64*)(r10 - 8) = r1; \ 1231 r2 = r10; \ 1232 r2 += -8; \ 1233 r1 = %[map_array_48b] ll; \ 1234 call %[bpf_map_lookup_elem]; \ 1235 if r0 == 0 goto l0_%=; \ 1236 r1 = 6; \ 1237 r2 = 4; \ 1238 r0 += r1; \ 1239 r0 -= r2; \ 1240 r1 = *(u8*)(r0 + 0); \ 1241 l0_%=: r0 = 1; \ 1242 exit; \ 1243 " : 1244 : __imm(bpf_map_lookup_elem), 1245 __imm_addr(map_array_48b) 1246 : __clobber_all); 1247 } 1248 1249 SEC("socket") 1250 __description("map access: unknown scalar -= value_ptr") 1251 __failure __msg("R1 tried to subtract pointer from scalar") 1252 __failure_unpriv 1253 __naked void access_unknown_scalar_value_ptr(void) 1254 { 1255 asm volatile (" \ 1256 r1 = 0; \ 1257 *(u64*)(r10 - 8) = r1; \ 1258 r2 = r10; \ 1259 r2 += -8; \ 1260 r1 = %[map_array_48b] ll; \ 1261 call %[bpf_map_lookup_elem]; \ 1262 if r0 == 0 goto l0_%=; \ 1263 r1 = *(u8*)(r0 + 0); \ 1264 r1 &= 0xf; \ 1265 r1 -= r0; \ 1266 r0 = *(u8*)(r1 + 0); \ 1267 l0_%=: r0 = 1; \ 1268 exit; \ 1269 " : 1270 : __imm(bpf_map_lookup_elem), 1271 __imm_addr(map_array_48b) 1272 : __clobber_all); 1273 } 1274 1275 SEC("socket") 1276 __description("map access: value_ptr -= unknown scalar") 1277 __failure __msg("R0 min value is negative") 1278 __failure_unpriv 1279 __naked void access_value_ptr_unknown_scalar(void) 1280 { 1281 asm volatile (" \ 1282 r1 = 0; \ 1283 *(u64*)(r10 - 8) = r1; \ 1284 r2 = r10; \ 1285 r2 += -8; \ 1286 r1 = %[map_array_48b] ll; \ 1287 call %[bpf_map_lookup_elem]; \ 1288 if r0 == 0 goto l0_%=; \ 1289 r1 = *(u8*)(r0 + 0); \ 1290 r1 &= 0xf; \ 1291 r0 -= r1; \ 1292 r1 = *(u8*)(r0 + 0); \ 1293 l0_%=: r0 = 1; \ 1294 exit; \ 1295 " : 1296 : __imm(bpf_map_lookup_elem), 1297 __imm_addr(map_array_48b) 1298 : __clobber_all); 1299 } 1300 1301 SEC("socket") 1302 __description("map access: value_ptr -= unknown scalar, 2") 1303 __success __success_unpriv 1304 __retval(1) 1305 #ifdef SPEC_V1 1306 __xlated_unpriv("r1 &= 7") 1307 __xlated_unpriv("nospec") /* inserted to prevent `R0 pointer arithmetic of map value goes out of range` */ 1308 __xlated_unpriv("r0 -= r1") 1309 #endif 1310 __naked void value_ptr_unknown_scalar_2_2(void) 1311 { 1312 asm volatile (" \ 1313 r1 = 0; \ 1314 *(u64*)(r10 - 8) = r1; \ 1315 r2 = r10; \ 1316 r2 += -8; \ 1317 r1 = %[map_array_48b] ll; \ 1318 call %[bpf_map_lookup_elem]; \ 1319 if r0 == 0 goto l0_%=; \ 1320 r1 = *(u8*)(r0 + 0); \ 1321 r1 &= 0xf; \ 1322 r1 |= 0x7; \ 1323 r0 += r1; \ 1324 r1 = *(u8*)(r0 + 0); \ 1325 r1 &= 0x7; \ 1326 r0 -= r1; \ 1327 r1 = *(u8*)(r0 + 0); \ 1328 l0_%=: r0 = 1; \ 1329 exit; \ 1330 " : 1331 : __imm(bpf_map_lookup_elem), 1332 __imm_addr(map_array_48b) 1333 : __clobber_all); 1334 } 1335 1336 SEC("socket") 1337 __description("map access: value_ptr -= value_ptr") 1338 __failure __msg("R0 invalid mem access 'scalar'") 1339 __msg_unpriv("R0 pointer -= pointer prohibited") 1340 __naked void access_value_ptr_value_ptr_2(void) 1341 { 1342 asm volatile (" \ 1343 r1 = 0; \ 1344 *(u64*)(r10 - 8) = r1; \ 1345 r2 = r10; \ 1346 r2 += -8; \ 1347 r1 = %[map_array_48b] ll; \ 1348 call %[bpf_map_lookup_elem]; \ 1349 if r0 == 0 goto l0_%=; \ 1350 r0 -= r0; \ 1351 r1 = *(u8*)(r0 + 0); \ 1352 l0_%=: r0 = 1; \ 1353 exit; \ 1354 " : 1355 : __imm(bpf_map_lookup_elem), 1356 __imm_addr(map_array_48b) 1357 : __clobber_all); 1358 } 1359 1360 SEC("socket") 1361 __description("map access: trying to leak tainted dst reg") 1362 __failure __msg("math between map_value pointer and 4294967295 is not allowed") 1363 __failure_unpriv 1364 __naked void to_leak_tainted_dst_reg(void) 1365 { 1366 asm volatile (" \ 1367 r0 = 0; \ 1368 r1 = 0; \ 1369 *(u64*)(r10 - 8) = r1; \ 1370 r2 = r10; \ 1371 r2 += -8; \ 1372 r1 = %[map_array_48b] ll; \ 1373 call %[bpf_map_lookup_elem]; \ 1374 if r0 != 0 goto l0_%=; \ 1375 exit; \ 1376 l0_%=: r2 = r0; \ 1377 w1 = 0xFFFFFFFF; \ 1378 w1 = w1; \ 1379 r2 -= r1; \ 1380 *(u64*)(r0 + 0) = r2; \ 1381 r0 = 0; \ 1382 exit; \ 1383 " : 1384 : __imm(bpf_map_lookup_elem), 1385 __imm_addr(map_array_48b) 1386 : __clobber_all); 1387 } 1388 1389 SEC("tc") 1390 __description("32bit pkt_ptr -= scalar") 1391 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 1392 __naked void _32bit_pkt_ptr_scalar(void) 1393 { 1394 asm volatile (" \ 1395 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 1396 r7 = *(u32*)(r1 + %[__sk_buff_data]); \ 1397 r6 = r7; \ 1398 r6 += 40; \ 1399 if r6 > r8 goto l0_%=; \ 1400 w4 = w7; \ 1401 w6 -= w4; \ 1402 l0_%=: r0 = 0; \ 1403 exit; \ 1404 " : 1405 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 1406 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 1407 : __clobber_all); 1408 } 1409 1410 SEC("tc") 1411 __description("32bit scalar -= pkt_ptr") 1412 __success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 1413 __naked void _32bit_scalar_pkt_ptr(void) 1414 { 1415 asm volatile (" \ 1416 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 1417 r7 = *(u32*)(r1 + %[__sk_buff_data]); \ 1418 r6 = r7; \ 1419 r6 += 40; \ 1420 if r6 > r8 goto l0_%=; \ 1421 w4 = w6; \ 1422 w4 -= w7; \ 1423 l0_%=: r0 = 0; \ 1424 exit; \ 1425 " : 1426 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 1427 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 1428 : __clobber_all); 1429 } 1430 1431 char _license[] SEC("license") = "GPL"; 1432