1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Nandakumar Edamana */ 3 #include <linux/bpf.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_tracing.h> 6 #include "bpf_misc.h" 7 8 /* Intended to test the abstract multiplication technique(s) used by 9 * the verifier. Using assembly to avoid compiler optimizations. 10 */ 11 SEC("fentry/bpf_fentry_test1") 12 void BPF_PROG(mul_precise, int x) 13 { 14 /* First, force the verifier to be uncertain about the value: 15 * unsigned int a = (bpf_get_prandom_u32() & 0x2) | 0x1; 16 * 17 * Assuming the verifier is using tnum, a must be tnum{.v=0x1, .m=0x2}. 18 * Then a * 0x3 would be m0m1 (m for uncertain). Added imprecision 19 * would cause the following to fail, because the required return value 20 * is 0: 21 * return (a * 0x3) & 0x4); 22 */ 23 asm volatile ("\ 24 call %[bpf_get_prandom_u32];\ 25 r0 &= 0x2;\ 26 r0 |= 0x1;\ 27 r0 *= 0x3;\ 28 r0 &= 0x4;\ 29 if r0 != 0 goto l0_%=;\ 30 r0 = 0;\ 31 goto l1_%=;\ 32 l0_%=:\ 33 r0 = 1;\ 34 l1_%=:\ 35 " : 36 : __imm(bpf_get_prandom_u32) 37 : __clobber_all); 38 } 39