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