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

Configure Feed

Select the types of activity you want to include in your feed.

at master 1439 lines 35 kB view raw
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 negative") 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 negative") 687__naked void lower_oob_arith_test_1(void) 688{ 689 asm volatile (" \ 690 r1 = 0; \ 691 *(u64*)(r10 - 8) = r1; \ 692 r2 = r10; \ 693 r2 += -8; \ 694 r1 = %[map_array_48b] ll; \ 695 call %[bpf_map_lookup_elem]; \ 696 if r0 == 0 goto l0_%=; \ 697 r1 = 47; \ 698 r0 += r1; \ 699 r1 = 48; \ 700 r0 -= r1; \ 701 r0 = *(u8*)(r0 + 0); \ 702l0_%=: r0 = 1; \ 703 exit; \ 704" : 705 : __imm(bpf_map_lookup_elem), 706 __imm_addr(map_array_48b) 707 : __clobber_all); 708} 709 710SEC("socket") 711__description("map access: value_ptr -= known scalar, lower oob arith, test 2") 712__success __failure_unpriv 713__msg_unpriv("R0 pointer arithmetic of map value goes out of range") 714__retval(1) 715__naked void lower_oob_arith_test_2(void) 716{ 717 asm volatile (" \ 718 r1 = 0; \ 719 *(u64*)(r10 - 8) = r1; \ 720 r2 = r10; \ 721 r2 += -8; \ 722 r1 = %[map_array_48b] ll; \ 723 call %[bpf_map_lookup_elem]; \ 724 if r0 == 0 goto l0_%=; \ 725 r1 = 47; \ 726 r0 += r1; \ 727 r1 = 48; \ 728 r0 -= r1; \ 729 r1 = 1; \ 730 r0 += r1; \ 731 r0 = *(u8*)(r0 + 0); \ 732l0_%=: r0 = 1; \ 733 exit; \ 734" : 735 : __imm(bpf_map_lookup_elem), 736 __imm_addr(map_array_48b) 737 : __clobber_all); 738} 739 740SEC("socket") 741__description("map access: value_ptr -= known scalar, lower oob arith, test 3") 742__success __success_unpriv __retval(1) 743__naked void lower_oob_arith_test_3(void) 744{ 745 asm volatile (" \ 746 r1 = 0; \ 747 *(u64*)(r10 - 8) = r1; \ 748 r2 = r10; \ 749 r2 += -8; \ 750 r1 = %[map_array_48b] ll; \ 751 call %[bpf_map_lookup_elem]; \ 752 if r0 == 0 goto l0_%=; \ 753 r1 = 47; \ 754 r0 += r1; \ 755 r1 = 47; \ 756 r0 -= r1; \ 757 r0 = *(u8*)(r0 + 0); \ 758l0_%=: r0 = 1; \ 759 exit; \ 760" : 761 : __imm(bpf_map_lookup_elem), 762 __imm_addr(map_array_48b) 763 : __clobber_all); 764} 765 766SEC("socket") 767__description("map access: known scalar += value_ptr") 768__success __success_unpriv __retval(1) 769__naked void access_known_scalar_value_ptr_1(void) 770{ 771 asm volatile (" \ 772 r1 = 0; \ 773 *(u64*)(r10 - 8) = r1; \ 774 r2 = r10; \ 775 r2 += -8; \ 776 r1 = %[map_array_48b] ll; \ 777 call %[bpf_map_lookup_elem]; \ 778 if r0 == 0 goto l0_%=; \ 779 r1 = 4; \ 780 r1 += r0; \ 781 r0 = *(u8*)(r1 + 0); \ 782l0_%=: r0 = 1; \ 783 exit; \ 784" : 785 : __imm(bpf_map_lookup_elem), 786 __imm_addr(map_array_48b) 787 : __clobber_all); 788} 789 790SEC("socket") 791__description("map access: value_ptr += known scalar, 1") 792__success __success_unpriv __retval(1) 793__naked void value_ptr_known_scalar_1(void) 794{ 795 asm volatile (" \ 796 r1 = 0; \ 797 *(u64*)(r10 - 8) = r1; \ 798 r2 = r10; \ 799 r2 += -8; \ 800 r1 = %[map_array_48b] ll; \ 801 call %[bpf_map_lookup_elem]; \ 802 if r0 == 0 goto l0_%=; \ 803 r1 = 4; \ 804 r0 += r1; \ 805 r1 = *(u8*)(r0 + 0); \ 806l0_%=: r0 = 1; \ 807 exit; \ 808" : 809 : __imm(bpf_map_lookup_elem), 810 __imm_addr(map_array_48b) 811 : __clobber_all); 812} 813 814SEC("socket") 815__description("map access: value_ptr += known scalar, 2") 816__failure __msg("invalid access to map value") 817__failure_unpriv 818__naked void value_ptr_known_scalar_2_1(void) 819{ 820 asm volatile (" \ 821 r1 = 0; \ 822 *(u64*)(r10 - 8) = r1; \ 823 r2 = r10; \ 824 r2 += -8; \ 825 r1 = %[map_array_48b] ll; \ 826 call %[bpf_map_lookup_elem]; \ 827 if r0 == 0 goto l0_%=; \ 828 r1 = 49; \ 829 r0 += r1; \ 830 r1 = *(u8*)(r0 + 0); \ 831l0_%=: r0 = 1; \ 832 exit; \ 833" : 834 : __imm(bpf_map_lookup_elem), 835 __imm_addr(map_array_48b) 836 : __clobber_all); 837} 838 839SEC("socket") 840__description("map access: value_ptr += known scalar, 3") 841__failure __msg("R0 min value is negative") 842__failure_unpriv 843__naked void value_ptr_known_scalar_3(void) 844{ 845 asm volatile (" \ 846 r1 = 0; \ 847 *(u64*)(r10 - 8) = r1; \ 848 r2 = r10; \ 849 r2 += -8; \ 850 r1 = %[map_array_48b] ll; \ 851 call %[bpf_map_lookup_elem]; \ 852 if r0 == 0 goto l0_%=; \ 853 r1 = -1; \ 854 r0 += r1; \ 855 r1 = *(u8*)(r0 + 0); \ 856l0_%=: r0 = 1; \ 857 exit; \ 858" : 859 : __imm(bpf_map_lookup_elem), 860 __imm_addr(map_array_48b) 861 : __clobber_all); 862} 863 864SEC("socket") 865__description("map access: value_ptr += known scalar, 4") 866__success __success_unpriv __retval(1) 867__naked void value_ptr_known_scalar_4(void) 868{ 869 asm volatile (" \ 870 r1 = 0; \ 871 *(u64*)(r10 - 8) = r1; \ 872 r2 = r10; \ 873 r2 += -8; \ 874 r1 = %[map_array_48b] ll; \ 875 call %[bpf_map_lookup_elem]; \ 876 if r0 == 0 goto l0_%=; \ 877 r1 = 5; \ 878 r0 += r1; \ 879 r1 = -2; \ 880 r0 += r1; \ 881 r1 = -1; \ 882 r0 += r1; \ 883 r1 = *(u8*)(r0 + 0); \ 884l0_%=: r0 = 1; \ 885 exit; \ 886" : 887 : __imm(bpf_map_lookup_elem), 888 __imm_addr(map_array_48b) 889 : __clobber_all); 890} 891 892SEC("socket") 893__description("map access: value_ptr += known scalar, 5") 894__success __success_unpriv __retval(0xabcdef12) 895__naked void value_ptr_known_scalar_5(void) 896{ 897 asm volatile (" \ 898 r1 = 0; \ 899 *(u64*)(r10 - 8) = r1; \ 900 r2 = r10; \ 901 r2 += -8; \ 902 r1 = %[map_array_48b] ll; \ 903 call %[bpf_map_lookup_elem]; \ 904 if r0 == 0 goto l0_%=; \ 905 r1 = %[__imm_0]; \ 906 r1 += r0; \ 907 r0 = *(u32*)(r1 + 0); \ 908l0_%=: exit; \ 909" : 910 : __imm(bpf_map_lookup_elem), 911 __imm_addr(map_array_48b), 912 __imm_const(__imm_0, (6 + 1) * sizeof(int)) 913 : __clobber_all); 914} 915 916SEC("socket") 917__description("map access: value_ptr += known scalar, 6") 918__success __success_unpriv __retval(0xabcdef12) 919__naked void value_ptr_known_scalar_6(void) 920{ 921 asm volatile (" \ 922 r1 = 0; \ 923 *(u64*)(r10 - 8) = r1; \ 924 r2 = r10; \ 925 r2 += -8; \ 926 r1 = %[map_array_48b] ll; \ 927 call %[bpf_map_lookup_elem]; \ 928 if r0 == 0 goto l0_%=; \ 929 r1 = %[__imm_0]; \ 930 r0 += r1; \ 931 r1 = %[__imm_1]; \ 932 r0 += r1; \ 933 r0 = *(u32*)(r0 + 0); \ 934l0_%=: exit; \ 935" : 936 : __imm(bpf_map_lookup_elem), 937 __imm_addr(map_array_48b), 938 __imm_const(__imm_0, (3 + 1) * sizeof(int)), 939 __imm_const(__imm_1, 3 * sizeof(int)) 940 : __clobber_all); 941} 942 943SEC("socket") 944__description("map access: value_ptr += N, value_ptr -= N known scalar") 945__success __success_unpriv __retval(0x12345678) 946__naked void value_ptr_n_known_scalar(void) 947{ 948 asm volatile (" \ 949 r1 = 0; \ 950 *(u64*)(r10 - 8) = r1; \ 951 r2 = r10; \ 952 r2 += -8; \ 953 r1 = %[map_array_48b] ll; \ 954 call %[bpf_map_lookup_elem]; \ 955 if r0 == 0 goto l0_%=; \ 956 w1 = 0x12345678; \ 957 *(u32*)(r0 + 0) = r1; \ 958 r0 += 2; \ 959 r1 = 2; \ 960 r0 -= r1; \ 961 r0 = *(u32*)(r0 + 0); \ 962l0_%=: exit; \ 963" : 964 : __imm(bpf_map_lookup_elem), 965 __imm_addr(map_array_48b) 966 : __clobber_all); 967} 968 969SEC("socket") 970__description("map access: unknown scalar += value_ptr, 1") 971__success __success_unpriv __retval(1) 972__naked void unknown_scalar_value_ptr_1(void) 973{ 974 asm volatile (" \ 975 r1 = 0; \ 976 *(u64*)(r10 - 8) = r1; \ 977 r2 = r10; \ 978 r2 += -8; \ 979 r1 = %[map_array_48b] ll; \ 980 call %[bpf_map_lookup_elem]; \ 981 if r0 == 0 goto l0_%=; \ 982 r1 = *(u8*)(r0 + 0); \ 983 r1 &= 0xf; \ 984 r1 += r0; \ 985 r0 = *(u8*)(r1 + 0); \ 986l0_%=: r0 = 1; \ 987 exit; \ 988" : 989 : __imm(bpf_map_lookup_elem), 990 __imm_addr(map_array_48b) 991 : __clobber_all); 992} 993 994SEC("socket") 995__description("map access: unknown scalar += value_ptr, 2") 996__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 997__naked void unknown_scalar_value_ptr_2(void) 998{ 999 asm volatile (" \ 1000 r1 = 0; \ 1001 *(u64*)(r10 - 8) = r1; \ 1002 r2 = r10; \ 1003 r2 += -8; \ 1004 r1 = %[map_array_48b] ll; \ 1005 call %[bpf_map_lookup_elem]; \ 1006 if r0 == 0 goto l0_%=; \ 1007 r1 = *(u32*)(r0 + 0); \ 1008 r1 &= 31; \ 1009 r1 += r0; \ 1010 r0 = *(u32*)(r1 + 0); \ 1011l0_%=: exit; \ 1012" : 1013 : __imm(bpf_map_lookup_elem), 1014 __imm_addr(map_array_48b) 1015 : __clobber_all); 1016} 1017 1018SEC("socket") 1019__description("map access: unknown scalar += value_ptr, 3") 1020__success __failure_unpriv 1021__msg_unpriv("R0 pointer arithmetic of map value goes out of range") 1022__retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 1023__naked void unknown_scalar_value_ptr_3(void) 1024{ 1025 asm volatile (" \ 1026 r1 = 0; \ 1027 *(u64*)(r10 - 8) = r1; \ 1028 r2 = r10; \ 1029 r2 += -8; \ 1030 r1 = %[map_array_48b] ll; \ 1031 call %[bpf_map_lookup_elem]; \ 1032 if r0 == 0 goto l0_%=; \ 1033 r1 = -1; \ 1034 r0 += r1; \ 1035 r1 = 1; \ 1036 r0 += r1; \ 1037 r1 = *(u32*)(r0 + 0); \ 1038 r1 &= 31; \ 1039 r1 += r0; \ 1040 r0 = *(u32*)(r1 + 0); \ 1041l0_%=: exit; \ 1042" : 1043 : __imm(bpf_map_lookup_elem), 1044 __imm_addr(map_array_48b) 1045 : __clobber_all); 1046} 1047 1048SEC("socket") 1049__description("map access: unknown scalar += value_ptr, 4") 1050__failure __msg("R1 max value is outside of the allowed memory range") 1051__msg_unpriv("R1 pointer arithmetic of map value goes out of range") 1052__flag(BPF_F_ANY_ALIGNMENT) 1053__naked void unknown_scalar_value_ptr_4(void) 1054{ 1055 asm volatile (" \ 1056 r1 = 0; \ 1057 *(u64*)(r10 - 8) = r1; \ 1058 r2 = r10; \ 1059 r2 += -8; \ 1060 r1 = %[map_array_48b] ll; \ 1061 call %[bpf_map_lookup_elem]; \ 1062 if r0 == 0 goto l0_%=; \ 1063 r1 = 19; \ 1064 r0 += r1; \ 1065 r1 = *(u32*)(r0 + 0); \ 1066 r1 &= 31; \ 1067 r1 += r0; \ 1068 r0 = *(u32*)(r1 + 0); \ 1069l0_%=: exit; \ 1070" : 1071 : __imm(bpf_map_lookup_elem), 1072 __imm_addr(map_array_48b) 1073 : __clobber_all); 1074} 1075 1076SEC("socket") 1077__description("map access: value_ptr += unknown scalar, 1") 1078__success __success_unpriv __retval(1) 1079__naked void value_ptr_unknown_scalar_1(void) 1080{ 1081 asm volatile (" \ 1082 r1 = 0; \ 1083 *(u64*)(r10 - 8) = r1; \ 1084 r2 = r10; \ 1085 r2 += -8; \ 1086 r1 = %[map_array_48b] ll; \ 1087 call %[bpf_map_lookup_elem]; \ 1088 if r0 == 0 goto l0_%=; \ 1089 r1 = *(u8*)(r0 + 0); \ 1090 r1 &= 0xf; \ 1091 r0 += r1; \ 1092 r1 = *(u8*)(r0 + 0); \ 1093l0_%=: r0 = 1; \ 1094 exit; \ 1095" : 1096 : __imm(bpf_map_lookup_elem), 1097 __imm_addr(map_array_48b) 1098 : __clobber_all); 1099} 1100 1101SEC("socket") 1102__description("map access: value_ptr += unknown scalar, 2") 1103__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT) 1104__naked void value_ptr_unknown_scalar_2_1(void) 1105{ 1106 asm volatile (" \ 1107 r1 = 0; \ 1108 *(u64*)(r10 - 8) = r1; \ 1109 r2 = r10; \ 1110 r2 += -8; \ 1111 r1 = %[map_array_48b] ll; \ 1112 call %[bpf_map_lookup_elem]; \ 1113 if r0 == 0 goto l0_%=; \ 1114 r1 = *(u32*)(r0 + 0); \ 1115 r1 &= 31; \ 1116 r0 += r1; \ 1117 r0 = *(u32*)(r0 + 0); \ 1118l0_%=: exit; \ 1119" : 1120 : __imm(bpf_map_lookup_elem), 1121 __imm_addr(map_array_48b) 1122 : __clobber_all); 1123} 1124 1125SEC("socket") 1126__description("map access: value_ptr += unknown scalar, 3") 1127__success __success_unpriv __retval(1) 1128__naked void value_ptr_unknown_scalar_3(void) 1129{ 1130 asm volatile (" \ 1131 r1 = 0; \ 1132 *(u64*)(r10 - 8) = r1; \ 1133 r2 = r10; \ 1134 r2 += -8; \ 1135 r1 = %[map_array_48b] ll; \ 1136 call %[bpf_map_lookup_elem]; \ 1137 if r0 == 0 goto l0_%=; \ 1138 r1 = *(u64*)(r0 + 0); \ 1139 r2 = *(u64*)(r0 + 8); \ 1140 r3 = *(u64*)(r0 + 16); \ 1141 r1 &= 0xf; \ 1142 r3 &= 1; \ 1143 r3 |= 1; \ 1144 if r2 > r3 goto l0_%=; \ 1145 r0 += r3; \ 1146 r0 = *(u8*)(r0 + 0); \ 1147 r0 = 1; \ 1148l1_%=: exit; \ 1149l0_%=: r0 = 2; \ 1150 goto l1_%=; \ 1151" : 1152 : __imm(bpf_map_lookup_elem), 1153 __imm_addr(map_array_48b) 1154 : __clobber_all); 1155} 1156 1157SEC("socket") 1158__description("map access: value_ptr += value_ptr") 1159__failure __msg("R0 pointer += pointer prohibited") 1160__failure_unpriv 1161__naked void access_value_ptr_value_ptr_1(void) 1162{ 1163 asm volatile (" \ 1164 r1 = 0; \ 1165 *(u64*)(r10 - 8) = r1; \ 1166 r2 = r10; \ 1167 r2 += -8; \ 1168 r1 = %[map_array_48b] ll; \ 1169 call %[bpf_map_lookup_elem]; \ 1170 if r0 == 0 goto l0_%=; \ 1171 r0 += r0; \ 1172 r1 = *(u8*)(r0 + 0); \ 1173l0_%=: r0 = 1; \ 1174 exit; \ 1175" : 1176 : __imm(bpf_map_lookup_elem), 1177 __imm_addr(map_array_48b) 1178 : __clobber_all); 1179} 1180 1181SEC("socket") 1182__description("map access: known scalar -= value_ptr") 1183__failure __msg("R1 tried to subtract pointer from scalar") 1184__failure_unpriv 1185__naked void access_known_scalar_value_ptr_2(void) 1186{ 1187 asm volatile (" \ 1188 r1 = 0; \ 1189 *(u64*)(r10 - 8) = r1; \ 1190 r2 = r10; \ 1191 r2 += -8; \ 1192 r1 = %[map_array_48b] ll; \ 1193 call %[bpf_map_lookup_elem]; \ 1194 if r0 == 0 goto l0_%=; \ 1195 r1 = 4; \ 1196 r1 -= r0; \ 1197 r0 = *(u8*)(r1 + 0); \ 1198l0_%=: r0 = 1; \ 1199 exit; \ 1200" : 1201 : __imm(bpf_map_lookup_elem), 1202 __imm_addr(map_array_48b) 1203 : __clobber_all); 1204} 1205 1206SEC("socket") 1207__description("map access: value_ptr -= known scalar") 1208__failure __msg("R0 min value is negative") 1209__failure_unpriv 1210__naked void access_value_ptr_known_scalar(void) 1211{ 1212 asm volatile (" \ 1213 r1 = 0; \ 1214 *(u64*)(r10 - 8) = r1; \ 1215 r2 = r10; \ 1216 r2 += -8; \ 1217 r1 = %[map_array_48b] ll; \ 1218 call %[bpf_map_lookup_elem]; \ 1219 if r0 == 0 goto l0_%=; \ 1220 r1 = 4; \ 1221 r0 -= r1; \ 1222 r1 = *(u8*)(r0 + 0); \ 1223l0_%=: r0 = 1; \ 1224 exit; \ 1225" : 1226 : __imm(bpf_map_lookup_elem), 1227 __imm_addr(map_array_48b) 1228 : __clobber_all); 1229} 1230 1231SEC("socket") 1232__description("map access: value_ptr -= known scalar, 2") 1233__success __success_unpriv __retval(1) 1234__naked void value_ptr_known_scalar_2_2(void) 1235{ 1236 asm volatile (" \ 1237 r1 = 0; \ 1238 *(u64*)(r10 - 8) = r1; \ 1239 r2 = r10; \ 1240 r2 += -8; \ 1241 r1 = %[map_array_48b] ll; \ 1242 call %[bpf_map_lookup_elem]; \ 1243 if r0 == 0 goto l0_%=; \ 1244 r1 = 6; \ 1245 r2 = 4; \ 1246 r0 += r1; \ 1247 r0 -= r2; \ 1248 r1 = *(u8*)(r0 + 0); \ 1249l0_%=: r0 = 1; \ 1250 exit; \ 1251" : 1252 : __imm(bpf_map_lookup_elem), 1253 __imm_addr(map_array_48b) 1254 : __clobber_all); 1255} 1256 1257SEC("socket") 1258__description("map access: unknown scalar -= value_ptr") 1259__failure __msg("R1 tried to subtract pointer from scalar") 1260__failure_unpriv 1261__naked void access_unknown_scalar_value_ptr(void) 1262{ 1263 asm volatile (" \ 1264 r1 = 0; \ 1265 *(u64*)(r10 - 8) = r1; \ 1266 r2 = r10; \ 1267 r2 += -8; \ 1268 r1 = %[map_array_48b] ll; \ 1269 call %[bpf_map_lookup_elem]; \ 1270 if r0 == 0 goto l0_%=; \ 1271 r1 = *(u8*)(r0 + 0); \ 1272 r1 &= 0xf; \ 1273 r1 -= r0; \ 1274 r0 = *(u8*)(r1 + 0); \ 1275l0_%=: r0 = 1; \ 1276 exit; \ 1277" : 1278 : __imm(bpf_map_lookup_elem), 1279 __imm_addr(map_array_48b) 1280 : __clobber_all); 1281} 1282 1283SEC("socket") 1284__description("map access: value_ptr -= unknown scalar") 1285__failure __msg("R0 min value is negative") 1286__failure_unpriv 1287__naked void access_value_ptr_unknown_scalar(void) 1288{ 1289 asm volatile (" \ 1290 r1 = 0; \ 1291 *(u64*)(r10 - 8) = r1; \ 1292 r2 = r10; \ 1293 r2 += -8; \ 1294 r1 = %[map_array_48b] ll; \ 1295 call %[bpf_map_lookup_elem]; \ 1296 if r0 == 0 goto l0_%=; \ 1297 r1 = *(u8*)(r0 + 0); \ 1298 r1 &= 0xf; \ 1299 r0 -= r1; \ 1300 r1 = *(u8*)(r0 + 0); \ 1301l0_%=: r0 = 1; \ 1302 exit; \ 1303" : 1304 : __imm(bpf_map_lookup_elem), 1305 __imm_addr(map_array_48b) 1306 : __clobber_all); 1307} 1308 1309SEC("socket") 1310__description("map access: value_ptr -= unknown scalar, 2") 1311__success __success_unpriv 1312__retval(1) 1313#ifdef SPEC_V1 1314__xlated_unpriv("r1 &= 7") 1315__xlated_unpriv("nospec") /* inserted to prevent `R0 pointer arithmetic of map value goes out of range` */ 1316__xlated_unpriv("r0 -= r1") 1317#endif 1318__naked void value_ptr_unknown_scalar_2_2(void) 1319{ 1320 asm volatile (" \ 1321 r1 = 0; \ 1322 *(u64*)(r10 - 8) = r1; \ 1323 r2 = r10; \ 1324 r2 += -8; \ 1325 r1 = %[map_array_48b] ll; \ 1326 call %[bpf_map_lookup_elem]; \ 1327 if r0 == 0 goto l0_%=; \ 1328 r1 = *(u8*)(r0 + 0); \ 1329 r1 &= 0xf; \ 1330 r1 |= 0x7; \ 1331 r0 += r1; \ 1332 r1 = *(u8*)(r0 + 0); \ 1333 r1 &= 0x7; \ 1334 r0 -= r1; \ 1335 r1 = *(u8*)(r0 + 0); \ 1336l0_%=: r0 = 1; \ 1337 exit; \ 1338" : 1339 : __imm(bpf_map_lookup_elem), 1340 __imm_addr(map_array_48b) 1341 : __clobber_all); 1342} 1343 1344SEC("socket") 1345__description("map access: value_ptr -= value_ptr") 1346__failure __msg("R0 invalid mem access 'scalar'") 1347__msg_unpriv("R0 pointer -= pointer prohibited") 1348__naked void access_value_ptr_value_ptr_2(void) 1349{ 1350 asm volatile (" \ 1351 r1 = 0; \ 1352 *(u64*)(r10 - 8) = r1; \ 1353 r2 = r10; \ 1354 r2 += -8; \ 1355 r1 = %[map_array_48b] ll; \ 1356 call %[bpf_map_lookup_elem]; \ 1357 if r0 == 0 goto l0_%=; \ 1358 r0 -= r0; \ 1359 r1 = *(u8*)(r0 + 0); \ 1360l0_%=: r0 = 1; \ 1361 exit; \ 1362" : 1363 : __imm(bpf_map_lookup_elem), 1364 __imm_addr(map_array_48b) 1365 : __clobber_all); 1366} 1367 1368SEC("socket") 1369__description("map access: trying to leak tainted dst reg") 1370__failure __msg("math between map_value pointer and 4294967295 is not allowed") 1371__failure_unpriv 1372__naked void to_leak_tainted_dst_reg(void) 1373{ 1374 asm volatile (" \ 1375 r0 = 0; \ 1376 r1 = 0; \ 1377 *(u64*)(r10 - 8) = r1; \ 1378 r2 = r10; \ 1379 r2 += -8; \ 1380 r1 = %[map_array_48b] ll; \ 1381 call %[bpf_map_lookup_elem]; \ 1382 if r0 != 0 goto l0_%=; \ 1383 exit; \ 1384l0_%=: r2 = r0; \ 1385 w1 = 0xFFFFFFFF; \ 1386 w1 = w1; \ 1387 r2 -= r1; \ 1388 *(u64*)(r0 + 0) = r2; \ 1389 r0 = 0; \ 1390 exit; \ 1391" : 1392 : __imm(bpf_map_lookup_elem), 1393 __imm_addr(map_array_48b) 1394 : __clobber_all); 1395} 1396 1397SEC("tc") 1398__description("32bit pkt_ptr -= scalar") 1399__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 1400__naked void _32bit_pkt_ptr_scalar(void) 1401{ 1402 asm volatile (" \ 1403 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 1404 r7 = *(u32*)(r1 + %[__sk_buff_data]); \ 1405 r6 = r7; \ 1406 r6 += 40; \ 1407 if r6 > r8 goto l0_%=; \ 1408 w4 = w7; \ 1409 w6 -= w4; \ 1410l0_%=: r0 = 0; \ 1411 exit; \ 1412" : 1413 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 1414 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 1415 : __clobber_all); 1416} 1417 1418SEC("tc") 1419__description("32bit scalar -= pkt_ptr") 1420__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT) 1421__naked void _32bit_scalar_pkt_ptr(void) 1422{ 1423 asm volatile (" \ 1424 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 1425 r7 = *(u32*)(r1 + %[__sk_buff_data]); \ 1426 r6 = r7; \ 1427 r6 += 40; \ 1428 if r6 > r8 goto l0_%=; \ 1429 w4 = w6; \ 1430 w4 -= w7; \ 1431l0_%=: r0 = 0; \ 1432 exit; \ 1433" : 1434 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), 1435 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) 1436 : __clobber_all); 1437} 1438 1439char _license[] SEC("license") = "GPL";