1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/bpf.h> 3 #include <bpf/bpf_helpers.h> 4 #include <bpf/bpf_tracing.h> 5 #include <stdbool.h> 6 7 char _license[] SEC("license") = "GPL"; 8 9 __u64 uprobe_multi_func_1_addr = 0; 10 __u64 uprobe_multi_func_2_addr = 0; 11 __u64 uprobe_multi_func_3_addr = 0; 12 13 __u64 uprobe_multi_func_1_result = 0; 14 __u64 uprobe_multi_func_2_result = 0; 15 __u64 uprobe_multi_func_3_result = 0; 16 17 __u64 uretprobe_multi_func_1_result = 0; 18 __u64 uretprobe_multi_func_2_result = 0; 19 __u64 uretprobe_multi_func_3_result = 0; 20 21 __u64 uprobe_multi_sleep_result = 0; 22 23 int pid = 0; 24 int child_pid = 0; 25 26 bool test_cookie = false; 27 void *user_ptr = 0; 28 29 static __always_inline bool verify_sleepable_user_copy(void) 30 { 31 char data[9]; 32 33 bpf_copy_from_user(data, sizeof(data), user_ptr); 34 return bpf_strncmp(data, sizeof(data), "test_data") == 0; 35 } 36 37 static void uprobe_multi_check(void *ctx, bool is_return, bool is_sleep) 38 { 39 child_pid = bpf_get_current_pid_tgid() >> 32; 40 41 if (pid && child_pid != pid) 42 return; 43 44 __u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0; 45 __u64 addr = bpf_get_func_ip(ctx); 46 47 #define SET(__var, __addr, __cookie) ({ \ 48 if (addr == __addr && \ 49 (!test_cookie || (cookie == __cookie))) \ 50 __var += 1; \ 51 }) 52 53 if (is_return) { 54 SET(uretprobe_multi_func_1_result, uprobe_multi_func_1_addr, 2); 55 SET(uretprobe_multi_func_2_result, uprobe_multi_func_2_addr, 3); 56 SET(uretprobe_multi_func_3_result, uprobe_multi_func_3_addr, 1); 57 } else { 58 SET(uprobe_multi_func_1_result, uprobe_multi_func_1_addr, 3); 59 SET(uprobe_multi_func_2_result, uprobe_multi_func_2_addr, 1); 60 SET(uprobe_multi_func_3_result, uprobe_multi_func_3_addr, 2); 61 } 62 63 #undef SET 64 65 if (is_sleep && verify_sleepable_user_copy()) 66 uprobe_multi_sleep_result += 1; 67 } 68 69 SEC("uprobe.multi//proc/self/exe:uprobe_multi_func_*") 70 int uprobe(struct pt_regs *ctx) 71 { 72 uprobe_multi_check(ctx, false, false); 73 return 0; 74 } 75 76 SEC("uretprobe.multi//proc/self/exe:uprobe_multi_func_*") 77 int uretprobe(struct pt_regs *ctx) 78 { 79 uprobe_multi_check(ctx, true, false); 80 return 0; 81 } 82 83 SEC("uprobe.multi.s//proc/self/exe:uprobe_multi_func_*") 84 int uprobe_sleep(struct pt_regs *ctx) 85 { 86 uprobe_multi_check(ctx, false, true); 87 return 0; 88 } 89 90 SEC("uretprobe.multi.s//proc/self/exe:uprobe_multi_func_*") 91 int uretprobe_sleep(struct pt_regs *ctx) 92 { 93 uprobe_multi_check(ctx, true, true); 94 return 0; 95 } 96 97 SEC("uprobe.multi//proc/self/exe:uprobe_multi_func_*") 98 int uprobe_extra(struct pt_regs *ctx) 99 { 100 return 0; 101 } 102