tools/testing/selftests/bpf/progs/verifier_subprog_precision.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
Extension
.c
Size
27834 bytes
Lines
850
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */

#include <errno.h>
#include <string.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include <../../../tools/include/linux/filter.h>

int vals[] SEC(".data.vals") = {1, 2, 3, 4};

__naked __noinline __used
static unsigned long identity_subprog()
{
	/* the simplest *static* 64-bit identity function */
	asm volatile (
		"r0 = r1;"
		"exit;"
	);
}

__noinline __used
unsigned long global_identity_subprog(__u64 x)
{
	/* the simplest *global* 64-bit identity function */
	return x;
}

__naked __noinline __used
static unsigned long callback_subprog()
{
	/* the simplest callback function */
	asm volatile (
		"r0 = 0;"
		"exit;"
	);
}

SEC("?raw_tp")
__success __log_level(2)
__msg("7: (0f) r1 += r0")
__msg("mark_precise: frame0: regs=r0 stack= before 6: (bf) r1 = r7")
__msg("mark_precise: frame0: regs=r0 stack= before 5: (27) r0 *= 4")
__msg("mark_precise: frame0: regs=r0 stack= before 11: (95) exit")
__msg("mark_precise: frame1: regs=r0 stack= before 10: (bf) r0 = r1")
__msg("mark_precise: frame1: regs=r1 stack= before 4: (85) call pc+5")
__msg("mark_precise: frame0: regs=r1 stack= before 3: (bf) r1 = r6")
__msg("mark_precise: frame0: regs=r6 stack= before 2: (b7) r6 = 3")
__naked int subprog_result_precise(void)
{
	asm volatile (
		"r6 = 3;"
		/* pass r6 through r1 into subprog to get it back as r0;
		 * this whole chain will have to be marked as precise later
		 */
		"r1 = r6;"
		"call identity_subprog;"
		/* now use subprog's returned value (which is a
		 * r6 -> r1 -> r0 chain), as index into vals array, forcing
		 * all of that to be known precisely
		 */
		"r0 *= 4;"
		"r1 = %[vals];"
		/* here r0->r1->r6 chain is forced to be precise and has to be
		 * propagated back to the beginning, including through the
		 * subprog call
		 */
		"r1 += r0;"
		"r0 = *(u32 *)(r1 + 0);"
		"exit;"
		:
		: __imm_ptr(vals)
		: __clobber_common, "r6"
	);
}

__naked __noinline __used
static unsigned long fp_leaking_subprog()
{
	asm volatile (
		".8byte %[r0_eq_r10_cast_s8];"
		"exit;"
		:: __imm_insn(r0_eq_r10_cast_s8, BPF_MOVSX64_REG(BPF_REG_0, BPF_REG_10, 8))
	);
}

__naked __noinline __used
static unsigned long sneaky_fp_leaking_subprog()
{

Annotation

Implementation Notes