Commit 2660b9d4 authored by Nandakumar Edamana's avatar Nandakumar Edamana Committed by Andrii Nakryiko
Browse files

bpf: Add selftest to check the verifier's abstract multiplication



Add new selftest to test the abstract multiplication technique(s) used
by the verifier, following the recent improvement in tnum
multiplication (tnum_mul). One of the newly added programs,
verifier_mul/mul_precise, results in a false positive with the old
tnum_mul, while the program passes with the latest one.

Signed-off-by: default avatarNandakumar Edamana <nandakumar@nandakumar.co.in>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Reviewed-by: default avatarHarishankar Vishwanathan <harishankar.vishwanathan@gmail.com>
Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20250826034524.2159515-2-nandakumar@nandakumar.co.in
parent 1df7dad4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include "verifier_meta_access.skel.h"
#include "verifier_movsx.skel.h"
#include "verifier_mtu.skel.h"
#include "verifier_mul.skel.h"
#include "verifier_netfilter_ctx.skel.h"
#include "verifier_netfilter_retcode.skel.h"
#include "verifier_bpf_fastcall.skel.h"
@@ -194,6 +195,7 @@ void test_verifier_may_goto_1(void) { RUN(verifier_may_goto_1); }
void test_verifier_may_goto_2(void)           { RUN(verifier_may_goto_2); }
void test_verifier_meta_access(void)          { RUN(verifier_meta_access); }
void test_verifier_movsx(void)                 { RUN(verifier_movsx); }
void test_verifier_mul(void)                  { RUN(verifier_mul); }
void test_verifier_netfilter_ctx(void)        { RUN(verifier_netfilter_ctx); }
void test_verifier_netfilter_retcode(void)    { RUN(verifier_netfilter_retcode); }
void test_verifier_bpf_fastcall(void)         { RUN(verifier_bpf_fastcall); }
+38 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Nandakumar Edamana */
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "bpf_misc.h"

/* Intended to test the abstract multiplication technique(s) used by
 * the verifier. Using assembly to avoid compiler optimizations.
 */
SEC("fentry/bpf_fentry_test1")
void BPF_PROG(mul_precise, int x)
{
	/* First, force the verifier to be uncertain about the value:
	 *     unsigned int a = (bpf_get_prandom_u32() & 0x2) | 0x1;
	 *
	 * Assuming the verifier is using tnum, a must be tnum{.v=0x1, .m=0x2}.
	 * Then a * 0x3 would be m0m1 (m for uncertain). Added imprecision
	 * would cause the following to fail, because the required return value
	 * is 0:
	 *     return (a * 0x3) & 0x4);
	 */
	asm volatile ("\
	call %[bpf_get_prandom_u32];\
	r0 &= 0x2;\
	r0 |= 0x1;\
	r0 *= 0x3;\
	r0 &= 0x4;\
	if r0 != 0 goto l0_%=;\
	r0 = 0;\
	goto l1_%=;\
l0_%=:\
	r0 = 1;\
l1_%=:\
"	:
	: __imm(bpf_get_prandom_u32)
	: __clobber_all);
}