125 lines · c
1#include "vmlinux.h"2#include <bpf/bpf_helpers.h>3#include <bpf/bpf_core_read.h>4 5const char LICENSE[] SEC("license") = "GPL";6 7struct {8 __uint(type, BPF_MAP_TYPE_ARRAY);9 __uint(max_entries, 1);10 __type(key, __u32);11 __type(value, __u64);12} array SEC(".maps");13 14__noinline int sub1(int x)15{16 int key = 0;17 18 bpf_map_lookup_elem(&array, &key);19 return x + 1;20}21 22static __noinline int sub5(int v);23 24__noinline int sub2(int y)25{26 return sub5(y + 2);27}28 29static __noinline int sub3(int z)30{31 return z + 3 + sub1(4);32}33 34static __noinline int sub4(int w)35{36 int key = 0;37 38 bpf_map_lookup_elem(&array, &key);39 return w + sub3(5) + sub1(6);40}41 42/* sub5() is an identitify function, just to test weirder functions layout and43 * call patterns44 */45static __noinline int sub5(int v)46{47 return sub1(v) - 1; /* compensates sub1()'s + 1 */48}49 50/* unfortunately verifier rejects `struct task_struct *t` as an unknown pointer51 * type, so we need to accept pointer as integer and then cast it inside the52 * function53 */54__noinline int get_task_tgid(uintptr_t t)55{56 /* this ensures that CO-RE relocs work in multi-subprogs .text */57 return BPF_CORE_READ((struct task_struct *)(void *)t, tgid);58}59 60int res1 = 0;61int res2 = 0;62int res3 = 0;63int res4 = 0;64 65SEC("raw_tp/sys_enter")66int prog1(void *ctx)67{68 /* perform some CO-RE relocations to ensure they work with multi-prog69 * sections correctly70 */71 struct task_struct *t = (void *)bpf_get_current_task();72 73 if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))74 return 1;75 76 res1 = sub1(1) + sub3(2); /* (1 + 1) + (2 + 3 + (4 + 1)) = 12 */77 return 0;78}79 80SEC("raw_tp/sys_exit")81int prog2(void *ctx)82{83 struct task_struct *t = (void *)bpf_get_current_task();84 85 if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))86 return 1;87 88 res2 = sub2(3) + sub3(4); /* (3 + 2) + (4 + 3 + (4 + 1)) = 17 */89 return 0;90}91 92static int empty_callback(__u32 index, void *data)93{94 return 0;95}96 97/* prog3 has the same section name as prog1 */98SEC("raw_tp/sys_enter")99int prog3(void *ctx)100{101 struct task_struct *t = (void *)bpf_get_current_task();102 103 if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))104 return 1;105 106 /* test that ld_imm64 with BPF_PSEUDO_FUNC doesn't get blinded */107 bpf_loop(1, empty_callback, NULL, 0);108 109 res3 = sub3(5) + 6; /* (5 + 3 + (4 + 1)) + 6 = 19 */110 return 0;111}112 113/* prog4 has the same section name as prog2 */114SEC("raw_tp/sys_exit")115int prog4(void *ctx)116{117 struct task_struct *t = (void *)bpf_get_current_task();118 119 if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))120 return 1;121 122 res4 = sub4(7) + sub1(8); /* (7 + (5 + 3 + (4 + 1)) + (6 + 1)) + (8 + 1) = 36 */123 return 0;124}125