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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/map_kptr_race.c
Extension
.c
Size
4036 bytes
Lines
198
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

struct map_value {
	struct prog_test_ref_kfunc __kptr *ref_ptr;
};

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct map_value);
	__uint(max_entries, 1);
} race_hash_map SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct map_value);
	__uint(max_entries, 1);
} race_percpu_hash_map SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_SK_STORAGE);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct map_value);
} race_sk_ls_map SEC(".maps");

int num_of_refs;
int sk_ls_leak_done;
int target_map_id;
int map_freed;
const volatile int nr_cpus;

SEC("tc")
int test_htab_leak(struct __sk_buff *skb)
{
	struct prog_test_ref_kfunc *p, *old;
	struct map_value val = {};
	struct map_value *v;
	int key = 0;

	if (bpf_map_update_elem(&race_hash_map, &key, &val, BPF_ANY))
		return 1;

	v = bpf_map_lookup_elem(&race_hash_map, &key);
	if (!v)
		return 2;

	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
	if (!p)
		return 3;
	old = bpf_kptr_xchg(&v->ref_ptr, p);
	if (old)
		bpf_kfunc_call_test_release(old);

	bpf_map_delete_elem(&race_hash_map, &key);

	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
	if (!p)
		return 4;
	old = bpf_kptr_xchg(&v->ref_ptr, p);
	if (old)
		bpf_kfunc_call_test_release(old);

	return 0;
}

static int fill_percpu_kptr(struct map_value *v)
{
	struct prog_test_ref_kfunc *p, *old;

	p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
	if (!p)
		return 1;
	old = bpf_kptr_xchg(&v->ref_ptr, p);
	if (old)
		bpf_kfunc_call_test_release(old);
	return 0;
}

SEC("tc")
int test_percpu_htab_leak(struct __sk_buff *skb)
{
	struct map_value *v, *arr[16] = {};
	struct map_value val = {};
	int key = 0;
	int err = 0;

	if (bpf_map_update_elem(&race_percpu_hash_map, &key, &val, BPF_ANY))
		return 1;

Annotation

Implementation Notes