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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
Extension
.c
Size
4030 bytes
Lines
186
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) 2026 Meta Platforms, Inc. and affiliates. */

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"

#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
	defined(__BPF_FEATURE_STACK_ARGUMENT)

__noinline __used __naked
static int subprog_bad_order_6args(int a, int b, int c, int d, int e, int f)
{
	asm volatile (
		"*(u64 *)(r11 - 8) = r1;"
		"r0 = *(u64 *)(r11 + 8);"
		"exit;"
		::: __clobber_all
	);
}

SEC("tc")
__description("stack_arg: r11 load after r11 store")
__failure
__msg("r11 load must be before any r11 store or call insn")
__btf_func_path("btf__verifier_stack_arg_order.bpf.o")
__naked void stack_arg_load_after_store(void)
{
	asm volatile (
		"r1 = 1;"
		"r2 = 2;"
		"r3 = 3;"
		"r4 = 4;"
		"r5 = 5;"
		"*(u64 *)(r11 - 8) = 6;"
		"call subprog_bad_order_6args;"
		"exit;"
		::: __clobber_all
	);
}

__noinline __used __naked
static int subprog_call_before_load_6args(int a, int b, int c, int d, int e,
					  int f)
{
	asm volatile (
		"call %[bpf_get_prandom_u32];"
		"r0 = *(u64 *)(r11 + 8);"
		"exit;"
		:: __imm(bpf_get_prandom_u32)
		: __clobber_all
	);
}

SEC("tc")
__description("stack_arg: r11 load after a call")
__failure
__msg("r11 load must be before any r11 store or call insn")
__btf_func_path("btf__verifier_stack_arg_order.bpf.o")
__naked void stack_arg_load_after_call(void)
{
	asm volatile (
		"r1 = 1;"
		"r2 = 2;"
		"r3 = 3;"
		"r4 = 4;"
		"r5 = 5;"
		"*(u64 *)(r11 - 8) = 6;"
		"call subprog_call_before_load_6args;"
		"exit;"
		::: __clobber_all
	);
}

__noinline __used __naked
static int subprog_pruning_call_before_load_6args(int a, int b, int c, int d,
						  int e, int f)
{
	asm volatile (
		"if r1 s> 0 goto l0_%=;"
		"goto l1_%=;"
	"l0_%=:"
		"call %[bpf_get_prandom_u32];"
	"l1_%=:"
		"r0 = *(u64 *)(r11 + 8);"
		"exit;"
		:: __imm(bpf_get_prandom_u32)
		: __clobber_all
	);
}

Annotation

Implementation Notes