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