1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/subreg.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_misc.h" 7 8 /* This file contains sub-register zero extension checks for insns defining 9 * sub-registers, meaning: 10 * - All insns under BPF_ALU class. Their BPF_ALU32 variants or narrow width 11 * forms (BPF_END) could define sub-registers. 12 * - Narrow direct loads, BPF_B/H/W | BPF_LDX. 13 * - BPF_LD is not exposed to JIT back-ends, so no need for testing. 14 * 15 * "get_prandom_u32" is used to initialize low 32-bit of some registers to 16 * prevent potential optimizations done by verifier or JIT back-ends which could 17 * optimize register back into constant when range info shows one register is a 18 * constant. 19 */ 20 21 SEC("socket") 22 __description("add32 reg zero extend check") 23 __success __success_unpriv __retval(0) 24 __naked void add32_reg_zero_extend_check(void) 25 { 26 asm volatile (" \ 27 call %[bpf_get_prandom_u32]; \ 28 r1 = r0; \ 29 r0 = 0x100000000 ll; \ 30 w0 += w1; \ 31 r0 >>= 32; \ 32 exit; \ 33 " : 34 : __imm(bpf_get_prandom_u32) 35 : __clobber_all); 36 } 37 38 SEC("socket") 39 __description("add32 imm zero extend check") 40 __success __success_unpriv __retval(0) 41 __naked void add32_imm_zero_extend_check(void) 42 { 43 asm volatile (" \ 44 call %[bpf_get_prandom_u32]; \ 45 r1 = 0x1000000000 ll; \ 46 r0 |= r1; \ 47 /* An insn could have no effect on the low 32-bit, for example:\ 48 * a = a + 0 \ 49 * a = a | 0 \ 50 * a = a & -1 \ 51 * But, they should still zero high 32-bit. \ 52 */ \ 53 w0 += 0; \ 54 r0 >>= 32; \ 55 r6 = r0; \ 56 call %[bpf_get_prandom_u32]; \ 57 r1 = 0x1000000000 ll; \ 58 r0 |= r1; \ 59 w0 += -2; \ 60 r0 >>= 32; \ 61 r0 |= r6; \ 62 exit; \ 63 " : 64 : __imm(bpf_get_prandom_u32) 65 : __clobber_all); 66 } 67 68 SEC("socket") 69 __description("sub32 reg zero extend check") 70 __success __success_unpriv __retval(0) 71 __naked void sub32_reg_zero_extend_check(void) 72 { 73 asm volatile (" \ 74 call %[bpf_get_prandom_u32]; \ 75 r1 = r0; \ 76 r0 = 0x1ffffffff ll; \ 77 w0 -= w1; \ 78 r0 >>= 32; \ 79 exit; \ 80 " : 81 : __imm(bpf_get_prandom_u32) 82 : __clobber_all); 83 } 84 85 SEC("socket") 86 __description("sub32 imm zero extend check") 87 __success __success_unpriv __retval(0) 88 __naked void sub32_imm_zero_extend_check(void) 89 { 90 asm volatile (" \ 91 call %[bpf_get_prandom_u32]; \ 92 r1 = 0x1000000000 ll; \ 93 r0 |= r1; \ 94 w0 -= 0; \ 95 r0 >>= 32; \ 96 r6 = r0; \ 97 call %[bpf_get_prandom_u32]; \ 98 r1 = 0x1000000000 ll; \ 99 r0 |= r1; \ 100 w0 -= 1; \ 101 r0 >>= 32; \ 102 r0 |= r6; \ 103 exit; \ 104 " : 105 : __imm(bpf_get_prandom_u32) 106 : __clobber_all); 107 } 108 109 SEC("socket") 110 __description("mul32 reg zero extend check") 111 __success __success_unpriv __retval(0) 112 __naked void mul32_reg_zero_extend_check(void) 113 { 114 asm volatile (" \ 115 call %[bpf_get_prandom_u32]; \ 116 r1 = r0; \ 117 r0 = 0x100000001 ll; \ 118 w0 *= w1; \ 119 r0 >>= 32; \ 120 exit; \ 121 " : 122 : __imm(bpf_get_prandom_u32) 123 : __clobber_all); 124 } 125 126 SEC("socket") 127 __description("mul32 imm zero extend check") 128 __success __success_unpriv __retval(0) 129 __naked void mul32_imm_zero_extend_check(void) 130 { 131 asm volatile (" \ 132 call %[bpf_get_prandom_u32]; \ 133 r1 = 0x1000000000 ll; \ 134 r0 |= r1; \ 135 w0 *= 1; \ 136 r0 >>= 32; \ 137 r6 = r0; \ 138 call %[bpf_get_prandom_u32]; \ 139 r1 = 0x1000000000 ll; \ 140 r0 |= r1; \ 141 w0 *= -1; \ 142 r0 >>= 32; \ 143 r0 |= r6; \ 144 exit; \ 145 " : 146 : __imm(bpf_get_prandom_u32) 147 : __clobber_all); 148 } 149 150 SEC("socket") 151 __description("div32 reg zero extend check") 152 __success __success_unpriv __retval(0) 153 __naked void div32_reg_zero_extend_check(void) 154 { 155 asm volatile (" \ 156 call %[bpf_get_prandom_u32]; \ 157 r1 = r0; \ 158 r0 = -1; \ 159 w0 /= w1; \ 160 r0 >>= 32; \ 161 exit; \ 162 " : 163 : __imm(bpf_get_prandom_u32) 164 : __clobber_all); 165 } 166 167 SEC("socket") 168 __description("div32 imm zero extend check") 169 __success __success_unpriv __retval(0) 170 __naked void div32_imm_zero_extend_check(void) 171 { 172 asm volatile (" \ 173 call %[bpf_get_prandom_u32]; \ 174 r1 = 0x1000000000 ll; \ 175 r0 |= r1; \ 176 w0 /= 1; \ 177 r0 >>= 32; \ 178 r6 = r0; \ 179 call %[bpf_get_prandom_u32]; \ 180 r1 = 0x1000000000 ll; \ 181 r0 |= r1; \ 182 w0 /= 2; \ 183 r0 >>= 32; \ 184 r0 |= r6; \ 185 exit; \ 186 " : 187 : __imm(bpf_get_prandom_u32) 188 : __clobber_all); 189 } 190 191 SEC("socket") 192 __description("or32 reg zero extend check") 193 __success __success_unpriv __retval(0) 194 __naked void or32_reg_zero_extend_check(void) 195 { 196 asm volatile (" \ 197 call %[bpf_get_prandom_u32]; \ 198 r1 = r0; \ 199 r0 = 0x100000001 ll; \ 200 w0 |= w1; \ 201 r0 >>= 32; \ 202 exit; \ 203 " : 204 : __imm(bpf_get_prandom_u32) 205 : __clobber_all); 206 } 207 208 SEC("socket") 209 __description("or32 imm zero extend check") 210 __success __success_unpriv __retval(0) 211 __naked void or32_imm_zero_extend_check(void) 212 { 213 asm volatile (" \ 214 call %[bpf_get_prandom_u32]; \ 215 r1 = 0x1000000000 ll; \ 216 r0 |= r1; \ 217 w0 |= 0; \ 218 r0 >>= 32; \ 219 r6 = r0; \ 220 call %[bpf_get_prandom_u32]; \ 221 r1 = 0x1000000000 ll; \ 222 r0 |= r1; \ 223 w0 |= 1; \ 224 r0 >>= 32; \ 225 r0 |= r6; \ 226 exit; \ 227 " : 228 : __imm(bpf_get_prandom_u32) 229 : __clobber_all); 230 } 231 232 SEC("socket") 233 __description("and32 reg zero extend check") 234 __success __success_unpriv __retval(0) 235 __naked void and32_reg_zero_extend_check(void) 236 { 237 asm volatile (" \ 238 call %[bpf_get_prandom_u32]; \ 239 r1 = 0x100000000 ll; \ 240 r1 |= r0; \ 241 r0 = 0x1ffffffff ll; \ 242 w0 &= w1; \ 243 r0 >>= 32; \ 244 exit; \ 245 " : 246 : __imm(bpf_get_prandom_u32) 247 : __clobber_all); 248 } 249 250 SEC("socket") 251 __description("and32 imm zero extend check") 252 __success __success_unpriv __retval(0) 253 __naked void and32_imm_zero_extend_check(void) 254 { 255 asm volatile (" \ 256 call %[bpf_get_prandom_u32]; \ 257 r1 = 0x1000000000 ll; \ 258 r0 |= r1; \ 259 w0 &= -1; \ 260 r0 >>= 32; \ 261 r6 = r0; \ 262 call %[bpf_get_prandom_u32]; \ 263 r1 = 0x1000000000 ll; \ 264 r0 |= r1; \ 265 w0 &= -2; \ 266 r0 >>= 32; \ 267 r0 |= r6; \ 268 exit; \ 269 " : 270 : __imm(bpf_get_prandom_u32) 271 : __clobber_all); 272 } 273 274 SEC("socket") 275 __description("lsh32 reg zero extend check") 276 __success __success_unpriv __retval(0) 277 __naked void lsh32_reg_zero_extend_check(void) 278 { 279 asm volatile (" \ 280 call %[bpf_get_prandom_u32]; \ 281 r1 = 0x100000000 ll; \ 282 r0 |= r1; \ 283 r1 = 1; \ 284 w0 <<= w1; \ 285 r0 >>= 32; \ 286 exit; \ 287 " : 288 : __imm(bpf_get_prandom_u32) 289 : __clobber_all); 290 } 291 292 SEC("socket") 293 __description("lsh32 imm zero extend check") 294 __success __success_unpriv __retval(0) 295 __naked void lsh32_imm_zero_extend_check(void) 296 { 297 asm volatile (" \ 298 call %[bpf_get_prandom_u32]; \ 299 r1 = 0x1000000000 ll; \ 300 r0 |= r1; \ 301 w0 <<= 0; \ 302 r0 >>= 32; \ 303 r6 = r0; \ 304 call %[bpf_get_prandom_u32]; \ 305 r1 = 0x1000000000 ll; \ 306 r0 |= r1; \ 307 w0 <<= 1; \ 308 r0 >>= 32; \ 309 r0 |= r6; \ 310 exit; \ 311 " : 312 : __imm(bpf_get_prandom_u32) 313 : __clobber_all); 314 } 315 316 SEC("socket") 317 __description("rsh32 reg zero extend check") 318 __success __success_unpriv __retval(0) 319 __naked void rsh32_reg_zero_extend_check(void) 320 { 321 asm volatile (" \ 322 call %[bpf_get_prandom_u32]; \ 323 r1 = 0x1000000000 ll; \ 324 r0 |= r1; \ 325 r1 = 1; \ 326 w0 >>= w1; \ 327 r0 >>= 32; \ 328 exit; \ 329 " : 330 : __imm(bpf_get_prandom_u32) 331 : __clobber_all); 332 } 333 334 SEC("socket") 335 __description("rsh32 imm zero extend check") 336 __success __success_unpriv __retval(0) 337 __naked void rsh32_imm_zero_extend_check(void) 338 { 339 asm volatile (" \ 340 call %[bpf_get_prandom_u32]; \ 341 r1 = 0x1000000000 ll; \ 342 r0 |= r1; \ 343 w0 >>= 0; \ 344 r0 >>= 32; \ 345 r6 = r0; \ 346 call %[bpf_get_prandom_u32]; \ 347 r1 = 0x1000000000 ll; \ 348 r0 |= r1; \ 349 w0 >>= 1; \ 350 r0 >>= 32; \ 351 r0 |= r6; \ 352 exit; \ 353 " : 354 : __imm(bpf_get_prandom_u32) 355 : __clobber_all); 356 } 357 358 SEC("socket") 359 __description("neg32 reg zero extend check") 360 __success __success_unpriv __retval(0) 361 __naked void neg32_reg_zero_extend_check(void) 362 { 363 asm volatile (" \ 364 call %[bpf_get_prandom_u32]; \ 365 r1 = 0x1000000000 ll; \ 366 r0 |= r1; \ 367 w0 = -w0; \ 368 r0 >>= 32; \ 369 exit; \ 370 " : 371 : __imm(bpf_get_prandom_u32) 372 : __clobber_all); 373 } 374 375 SEC("socket") 376 __description("mod32 reg zero extend check") 377 __success __success_unpriv __retval(0) 378 __naked void mod32_reg_zero_extend_check(void) 379 { 380 asm volatile (" \ 381 call %[bpf_get_prandom_u32]; \ 382 r1 = r0; \ 383 r0 = -1; \ 384 w0 %%= w1; \ 385 r0 >>= 32; \ 386 exit; \ 387 " : 388 : __imm(bpf_get_prandom_u32) 389 : __clobber_all); 390 } 391 392 SEC("socket") 393 __description("mod32 imm zero extend check") 394 __success __success_unpriv __retval(0) 395 __naked void mod32_imm_zero_extend_check(void) 396 { 397 asm volatile (" \ 398 call %[bpf_get_prandom_u32]; \ 399 r1 = 0x1000000000 ll; \ 400 r0 |= r1; \ 401 w0 %%= 1; \ 402 r0 >>= 32; \ 403 r6 = r0; \ 404 call %[bpf_get_prandom_u32]; \ 405 r1 = 0x1000000000 ll; \ 406 r0 |= r1; \ 407 w0 %%= 2; \ 408 r0 >>= 32; \ 409 r0 |= r6; \ 410 exit; \ 411 " : 412 : __imm(bpf_get_prandom_u32) 413 : __clobber_all); 414 } 415 416 SEC("socket") 417 __description("xor32 reg zero extend check") 418 __success __success_unpriv __retval(0) 419 __naked void xor32_reg_zero_extend_check(void) 420 { 421 asm volatile (" \ 422 call %[bpf_get_prandom_u32]; \ 423 r1 = r0; \ 424 r0 = 0x100000000 ll; \ 425 w0 ^= w1; \ 426 r0 >>= 32; \ 427 exit; \ 428 " : 429 : __imm(bpf_get_prandom_u32) 430 : __clobber_all); 431 } 432 433 SEC("socket") 434 __description("xor32 imm zero extend check") 435 __success __success_unpriv __retval(0) 436 __naked void xor32_imm_zero_extend_check(void) 437 { 438 asm volatile (" \ 439 call %[bpf_get_prandom_u32]; \ 440 r1 = 0x1000000000 ll; \ 441 r0 |= r1; \ 442 w0 ^= 1; \ 443 r0 >>= 32; \ 444 exit; \ 445 " : 446 : __imm(bpf_get_prandom_u32) 447 : __clobber_all); 448 } 449 450 SEC("socket") 451 __description("mov32 reg zero extend check") 452 __success __success_unpriv __retval(0) 453 __naked void mov32_reg_zero_extend_check(void) 454 { 455 asm volatile (" \ 456 call %[bpf_get_prandom_u32]; \ 457 r1 = 0x100000000 ll; \ 458 r1 |= r0; \ 459 r0 = 0x100000000 ll; \ 460 w0 = w1; \ 461 r0 >>= 32; \ 462 exit; \ 463 " : 464 : __imm(bpf_get_prandom_u32) 465 : __clobber_all); 466 } 467 468 SEC("socket") 469 __description("mov32 imm zero extend check") 470 __success __success_unpriv __retval(0) 471 __naked void mov32_imm_zero_extend_check(void) 472 { 473 asm volatile (" \ 474 call %[bpf_get_prandom_u32]; \ 475 r1 = 0x1000000000 ll; \ 476 r0 |= r1; \ 477 w0 = 0; \ 478 r0 >>= 32; \ 479 r6 = r0; \ 480 call %[bpf_get_prandom_u32]; \ 481 r1 = 0x1000000000 ll; \ 482 r0 |= r1; \ 483 w0 = 1; \ 484 r0 >>= 32; \ 485 r0 |= r6; \ 486 exit; \ 487 " : 488 : __imm(bpf_get_prandom_u32) 489 : __clobber_all); 490 } 491 492 SEC("socket") 493 __description("arsh32 reg zero extend check") 494 __success __success_unpriv __retval(0) 495 __naked void arsh32_reg_zero_extend_check(void) 496 { 497 asm volatile (" \ 498 call %[bpf_get_prandom_u32]; \ 499 r1 = 0x1000000000 ll; \ 500 r0 |= r1; \ 501 r1 = 1; \ 502 w0 s>>= w1; \ 503 r0 >>= 32; \ 504 exit; \ 505 " : 506 : __imm(bpf_get_prandom_u32) 507 : __clobber_all); 508 } 509 510 SEC("socket") 511 __description("arsh32 imm zero extend check") 512 __success __success_unpriv __retval(0) 513 __naked void arsh32_imm_zero_extend_check(void) 514 { 515 asm volatile (" \ 516 call %[bpf_get_prandom_u32]; \ 517 r1 = 0x1000000000 ll; \ 518 r0 |= r1; \ 519 w0 s>>= 0; \ 520 r0 >>= 32; \ 521 r6 = r0; \ 522 call %[bpf_get_prandom_u32]; \ 523 r1 = 0x1000000000 ll; \ 524 r0 |= r1; \ 525 w0 s>>= 1; \ 526 r0 >>= 32; \ 527 r0 |= r6; \ 528 exit; \ 529 " : 530 : __imm(bpf_get_prandom_u32) 531 : __clobber_all); 532 } 533 534 SEC("socket") 535 __description("arsh32 imm sign positive extend check") 536 __success __retval(0) 537 __log_level(2) 538 __msg("2: (57) r6 &= 4095 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))") 539 __msg("3: (67) r6 <<= 32 ; R6=scalar(smin=smin32=0,smax=umax=0xfff00000000,smax32=umax32=0,var_off=(0x0; 0xfff00000000))") 540 __msg("4: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))") 541 __naked void arsh32_imm_sign_extend_positive_check(void) 542 { 543 asm volatile (" \ 544 call %[bpf_get_prandom_u32]; \ 545 r6 = r0; \ 546 r6 &= 4095; \ 547 r6 <<= 32; \ 548 r6 s>>= 32; \ 549 r0 = 0; \ 550 exit; \ 551 " : 552 : __imm(bpf_get_prandom_u32) 553 : __clobber_all); 554 } 555 556 SEC("socket") 557 __description("arsh32 imm sign negative extend check") 558 __success __retval(0) 559 __log_level(2) 560 __msg("3: (17) r6 -= 4095 ; R6=scalar(smin=smin32=-4095,smax=smax32=0)") 561 __msg("4: (67) r6 <<= 32 ; R6=scalar(smin=0xfffff00100000000,smax=smax32=umax32=0,umax=0xffffffff00000000,smin32=0,var_off=(0x0; 0xffffffff00000000))") 562 __msg("5: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=-4095,smax=smax32=0)") 563 __naked void arsh32_imm_sign_extend_negative_check(void) 564 { 565 asm volatile (" \ 566 call %[bpf_get_prandom_u32]; \ 567 r6 = r0; \ 568 r6 &= 4095; \ 569 r6 -= 4095; \ 570 r6 <<= 32; \ 571 r6 s>>= 32; \ 572 r0 = 0; \ 573 exit; \ 574 " : 575 : __imm(bpf_get_prandom_u32) 576 : __clobber_all); 577 } 578 579 SEC("socket") 580 __description("arsh32 imm sign extend check") 581 __success __retval(0) 582 __log_level(2) 583 __msg("3: (17) r6 -= 2047 ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)") 584 __msg("4: (67) r6 <<= 32 ; R6=scalar(smin=0xfffff80100000000,smax=0x80000000000,umax=0xffffffff00000000,smin32=0,smax32=umax32=0,var_off=(0x0; 0xffffffff00000000))") 585 __msg("5: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)") 586 __naked void arsh32_imm_sign_extend_check(void) 587 { 588 asm volatile (" \ 589 call %[bpf_get_prandom_u32]; \ 590 r6 = r0; \ 591 r6 &= 4095; \ 592 r6 -= 2047; \ 593 r6 <<= 32; \ 594 r6 s>>= 32; \ 595 r0 = 0; \ 596 exit; \ 597 " : 598 : __imm(bpf_get_prandom_u32) 599 : __clobber_all); 600 } 601 602 SEC("socket") 603 __description("end16 (to_le) reg zero extend check") 604 __success __success_unpriv __retval(0) 605 __naked void le_reg_zero_extend_check_1(void) 606 { 607 asm volatile (" \ 608 call %[bpf_get_prandom_u32]; \ 609 r6 = r0; \ 610 r6 <<= 32; \ 611 call %[bpf_get_prandom_u32]; \ 612 r0 |= r6; \ 613 r0 = le16 r0; \ 614 r0 >>= 32; \ 615 exit; \ 616 " : 617 : __imm(bpf_get_prandom_u32) 618 : __clobber_all); 619 } 620 621 SEC("socket") 622 __description("end32 (to_le) reg zero extend check") 623 __success __success_unpriv __retval(0) 624 __naked void le_reg_zero_extend_check_2(void) 625 { 626 asm volatile (" \ 627 call %[bpf_get_prandom_u32]; \ 628 r6 = r0; \ 629 r6 <<= 32; \ 630 call %[bpf_get_prandom_u32]; \ 631 r0 |= r6; \ 632 r0 = le32 r0; \ 633 r0 >>= 32; \ 634 exit; \ 635 " : 636 : __imm(bpf_get_prandom_u32) 637 : __clobber_all); 638 } 639 640 SEC("socket") 641 __description("end16 (to_be) reg zero extend check") 642 __success __success_unpriv __retval(0) 643 __naked void be_reg_zero_extend_check_1(void) 644 { 645 asm volatile (" \ 646 call %[bpf_get_prandom_u32]; \ 647 r6 = r0; \ 648 r6 <<= 32; \ 649 call %[bpf_get_prandom_u32]; \ 650 r0 |= r6; \ 651 r0 = be16 r0; \ 652 r0 >>= 32; \ 653 exit; \ 654 " : 655 : __imm(bpf_get_prandom_u32) 656 : __clobber_all); 657 } 658 659 SEC("socket") 660 __description("end32 (to_be) reg zero extend check") 661 __success __success_unpriv __retval(0) 662 __naked void be_reg_zero_extend_check_2(void) 663 { 664 asm volatile (" \ 665 call %[bpf_get_prandom_u32]; \ 666 r6 = r0; \ 667 r6 <<= 32; \ 668 call %[bpf_get_prandom_u32]; \ 669 r0 |= r6; \ 670 r0 = be32 r0; \ 671 r0 >>= 32; \ 672 exit; \ 673 " : 674 : __imm(bpf_get_prandom_u32) 675 : __clobber_all); 676 } 677 678 SEC("socket") 679 __description("ldx_b zero extend check") 680 __success __success_unpriv __retval(0) 681 __naked void ldx_b_zero_extend_check(void) 682 { 683 asm volatile (" \ 684 r6 = r10; \ 685 r6 += -4; \ 686 r7 = 0xfaceb00c; \ 687 *(u32*)(r6 + 0) = r7; \ 688 call %[bpf_get_prandom_u32]; \ 689 r1 = 0x1000000000 ll; \ 690 r0 |= r1; \ 691 r0 = *(u8*)(r6 + 0); \ 692 r0 >>= 32; \ 693 exit; \ 694 " : 695 : __imm(bpf_get_prandom_u32) 696 : __clobber_all); 697 } 698 699 SEC("socket") 700 __description("ldx_h zero extend check") 701 __success __success_unpriv __retval(0) 702 __naked void ldx_h_zero_extend_check(void) 703 { 704 asm volatile (" \ 705 r6 = r10; \ 706 r6 += -4; \ 707 r7 = 0xfaceb00c; \ 708 *(u32*)(r6 + 0) = r7; \ 709 call %[bpf_get_prandom_u32]; \ 710 r1 = 0x1000000000 ll; \ 711 r0 |= r1; \ 712 r0 = *(u16*)(r6 + 0); \ 713 r0 >>= 32; \ 714 exit; \ 715 " : 716 : __imm(bpf_get_prandom_u32) 717 : __clobber_all); 718 } 719 720 SEC("socket") 721 __description("ldx_w zero extend check") 722 __success __success_unpriv __retval(0) 723 __naked void ldx_w_zero_extend_check(void) 724 { 725 asm volatile (" \ 726 r6 = r10; \ 727 r6 += -4; \ 728 r7 = 0xfaceb00c; \ 729 *(u32*)(r6 + 0) = r7; \ 730 call %[bpf_get_prandom_u32]; \ 731 r1 = 0x1000000000 ll; \ 732 r0 |= r1; \ 733 r0 = *(u32*)(r6 + 0); \ 734 r0 >>= 32; \ 735 exit; \ 736 " : 737 : __imm(bpf_get_prandom_u32) 738 : __clobber_all); 739 } 740 741 SEC("socket") 742 __success __success_unpriv __retval(0) 743 __naked void arsh_31_and(void) 744 { 745 /* Below is what LLVM generates in cilium's bpf_wiregard.o */ 746 asm volatile (" \ 747 call %[bpf_get_prandom_u32]; \ 748 w2 = w0; \ 749 w2 s>>= 31; \ 750 w2 &= -134; /* w2 becomes 0 or -134 */ \ 751 if w2 s> -1 goto +2; \ 752 /* Branch always taken because w2 = -134 */ \ 753 if w2 != -136 goto +1; \ 754 w0 /= 0; \ 755 w0 = 0; \ 756 exit; \ 757 " : 758 : __imm(bpf_get_prandom_u32) 759 : __clobber_all); 760 } 761 762 SEC("socket") 763 __success __success_unpriv __retval(0) 764 __naked void arsh_63_and(void) 765 { 766 /* Copy of arsh_31 with s/w/r/ */ 767 asm volatile (" \ 768 call %[bpf_get_prandom_u32]; \ 769 r2 = r0; \ 770 r2 <<= 32; \ 771 r2 s>>= 63; \ 772 r2 &= -134; \ 773 if r2 s> -1 goto +2; \ 774 /* Branch always taken because w2 = -134 */ \ 775 if r2 != -136 goto +1; \ 776 r0 /= 0; \ 777 r0 = 0; \ 778 exit; \ 779 " : 780 : __imm(bpf_get_prandom_u32) 781 : __clobber_all); 782 } 783 784 SEC("socket") 785 __success __success_unpriv __retval(0) 786 __naked void arsh_31_or(void) 787 { 788 asm volatile (" \ 789 call %[bpf_get_prandom_u32]; \ 790 w2 = w0; \ 791 w2 s>>= 31; \ 792 w2 |= 134; /* w2 becomes -1 or 134 */ \ 793 if w2 s> -1 goto +2; \ 794 /* Branch always taken because w2 = -1 */ \ 795 if w2 == -1 goto +1; \ 796 w0 /= 0; \ 797 w0 = 0; \ 798 exit; \ 799 " : 800 : __imm(bpf_get_prandom_u32) 801 : __clobber_all); 802 } 803 804 SEC("socket") 805 __success __success_unpriv __retval(0) 806 __naked void arsh_63_or(void) 807 { 808 /* Copy of arsh_31 with s/w/r/ */ 809 asm volatile (" \ 810 call %[bpf_get_prandom_u32]; \ 811 r2 = r0; \ 812 r2 <<= 32; \ 813 r2 s>>= 63; \ 814 r2 |= 134; /* r2 becomes -1 or 134 */ \ 815 if r2 s> -1 goto +2; \ 816 /* Branch always taken because w2 = -1 */ \ 817 if r2 == -1 goto +1; \ 818 r0 /= 0; \ 819 r0 = 0; \ 820 exit; \ 821 " : 822 : __imm(bpf_get_prandom_u32) 823 : __clobber_all); 824 } 825 826 char _license[] SEC("license") = "GPL"; 827