1ea4128ebSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
2ea4128ebSAndrii Nakryiko /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3ea4128ebSAndrii Nakryiko 
4ea4128ebSAndrii Nakryiko #include <linux/bpf.h>
5ea4128ebSAndrii Nakryiko #include <bpf/bpf_helpers.h>
6ea4128ebSAndrii Nakryiko #include <bpf/bpf_core_read.h>
7ea4128ebSAndrii Nakryiko 
8ea4128ebSAndrii Nakryiko struct task_struct___bad {
9ea4128ebSAndrii Nakryiko 	int pid;
10ea4128ebSAndrii Nakryiko 	int fake_field;
11ea4128ebSAndrii Nakryiko 	void *fake_field_subprog;
12ea4128ebSAndrii Nakryiko } __attribute__((preserve_access_index));
13ea4128ebSAndrii Nakryiko 
14ea4128ebSAndrii Nakryiko SEC("?raw_tp/sys_enter")
bad_relo(const void * ctx)15ea4128ebSAndrii Nakryiko int bad_relo(const void *ctx)
16ea4128ebSAndrii Nakryiko {
17ea4128ebSAndrii Nakryiko 	static struct task_struct___bad *t;
18ea4128ebSAndrii Nakryiko 
19ea4128ebSAndrii Nakryiko 	return bpf_core_field_size(t->fake_field);
20ea4128ebSAndrii Nakryiko }
21ea4128ebSAndrii Nakryiko 
bad_subprog(void)22ea4128ebSAndrii Nakryiko static __noinline int bad_subprog(void)
23ea4128ebSAndrii Nakryiko {
24ea4128ebSAndrii Nakryiko 	static struct task_struct___bad *t;
25ea4128ebSAndrii Nakryiko 
26ea4128ebSAndrii Nakryiko 	/* ugliness below is a field offset relocation */
27ea4128ebSAndrii Nakryiko 	return (void *)&t->fake_field_subprog - (void *)t;
28ea4128ebSAndrii Nakryiko }
29ea4128ebSAndrii Nakryiko 
30ea4128ebSAndrii Nakryiko SEC("?raw_tp/sys_enter")
bad_relo_subprog(const void * ctx)31ea4128ebSAndrii Nakryiko int bad_relo_subprog(const void *ctx)
32ea4128ebSAndrii Nakryiko {
33ea4128ebSAndrii Nakryiko 	static struct task_struct___bad *t;
34ea4128ebSAndrii Nakryiko 
35ea4128ebSAndrii Nakryiko 	return bad_subprog() + bpf_core_field_size(t->pid);
36ea4128ebSAndrii Nakryiko }
37ea4128ebSAndrii Nakryiko 
3868964e15SAndrii Nakryiko struct {
3968964e15SAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_ARRAY);
4068964e15SAndrii Nakryiko 	__uint(max_entries, 1);
4168964e15SAndrii Nakryiko 	__type(key, int);
4268964e15SAndrii Nakryiko 	__type(value, int);
4368964e15SAndrii Nakryiko } existing_map SEC(".maps");
4468964e15SAndrii Nakryiko 
4568964e15SAndrii Nakryiko struct {
4668964e15SAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_ARRAY);
4768964e15SAndrii Nakryiko 	__uint(max_entries, 1);
4868964e15SAndrii Nakryiko 	__type(key, int);
4968964e15SAndrii Nakryiko 	__type(value, int);
5068964e15SAndrii Nakryiko } missing_map SEC(".maps");
5168964e15SAndrii Nakryiko 
5268964e15SAndrii Nakryiko SEC("?raw_tp/sys_enter")
use_missing_map(const void * ctx)5368964e15SAndrii Nakryiko int use_missing_map(const void *ctx)
5468964e15SAndrii Nakryiko {
5568964e15SAndrii Nakryiko 	int zero = 0, *value;
5668964e15SAndrii Nakryiko 
5768964e15SAndrii Nakryiko 	value = bpf_map_lookup_elem(&existing_map, &zero);
5868964e15SAndrii Nakryiko 
5968964e15SAndrii Nakryiko 	value = bpf_map_lookup_elem(&missing_map, &zero);
6068964e15SAndrii Nakryiko 
6168964e15SAndrii Nakryiko 	return value != NULL;
6268964e15SAndrii Nakryiko }
6368964e15SAndrii Nakryiko 
64*30bbfe32SAndrii Nakryiko extern int bpf_nonexistent_kfunc(void) __ksym __weak;
65*30bbfe32SAndrii Nakryiko 
66*30bbfe32SAndrii Nakryiko SEC("?raw_tp/sys_enter")
use_missing_kfunc(const void * ctx)67*30bbfe32SAndrii Nakryiko int use_missing_kfunc(const void *ctx)
68*30bbfe32SAndrii Nakryiko {
69*30bbfe32SAndrii Nakryiko 	bpf_nonexistent_kfunc();
70*30bbfe32SAndrii Nakryiko 
71*30bbfe32SAndrii Nakryiko 	return 0;
72*30bbfe32SAndrii Nakryiko }
73*30bbfe32SAndrii Nakryiko 
74ea4128ebSAndrii Nakryiko char _license[] SEC("license") = "GPL";
75