1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2017 Facebook 3 4 #include <linux/ptrace.h> 5 #include <linux/bpf.h> 6 #include <bpf/bpf_helpers.h> 7 #include <bpf/bpf_tracing.h> 8 #include <stdbool.h> 9 #include "bpf_misc.h" 10 11 int kprobe_res = 0; 12 int kprobe2_res = 0; 13 int kretprobe_res = 0; 14 int kretprobe2_res = 0; 15 int uprobe_res = 0; 16 int uretprobe_res = 0; 17 int uprobe_byname_res = 0; 18 int uretprobe_byname_res = 0; 19 int uprobe_byname2_res = 0; 20 int uretprobe_byname2_res = 0; 21 int uprobe_byname3_sleepable_res = 0; 22 int uprobe_byname3_res = 0; 23 int uretprobe_byname3_sleepable_res = 0; 24 int uretprobe_byname3_res = 0; 25 void *user_ptr = 0; 26 27 SEC("kprobe") 28 int handle_kprobe(struct pt_regs *ctx) 29 { 30 kprobe_res = 1; 31 return 0; 32 } 33 34 SEC("kprobe/" SYS_PREFIX "sys_nanosleep") 35 int BPF_KPROBE(handle_kprobe_auto) 36 { 37 kprobe2_res = 11; 38 return 0; 39 } 40 41 /** 42 * This program will be manually made sleepable on the userspace side 43 * and should thus be unattachable. 44 */ 45 SEC("kprobe/" SYS_PREFIX "sys_nanosleep") 46 int handle_kprobe_sleepable(struct pt_regs *ctx) 47 { 48 kprobe_res = 2; 49 return 0; 50 } 51 52 SEC("kretprobe") 53 int handle_kretprobe(struct pt_regs *ctx) 54 { 55 kretprobe_res = 2; 56 return 0; 57 } 58 59 SEC("kretprobe/" SYS_PREFIX "sys_nanosleep") 60 int BPF_KRETPROBE(handle_kretprobe_auto) 61 { 62 kretprobe2_res = 22; 63 return 0; 64 } 65 66 SEC("uprobe") 67 int handle_uprobe(struct pt_regs *ctx) 68 { 69 uprobe_res = 3; 70 return 0; 71 } 72 73 SEC("uretprobe") 74 int handle_uretprobe(struct pt_regs *ctx) 75 { 76 uretprobe_res = 4; 77 return 0; 78 } 79 80 SEC("uprobe") 81 int handle_uprobe_byname(struct pt_regs *ctx) 82 { 83 uprobe_byname_res = 5; 84 return 0; 85 } 86 87 /* use auto-attach format for section definition. */ 88 SEC("uretprobe//proc/self/exe:trigger_func2") 89 int handle_uretprobe_byname(struct pt_regs *ctx) 90 { 91 uretprobe_byname_res = 6; 92 return 0; 93 } 94 95 SEC("uprobe") 96 int handle_uprobe_byname2(struct pt_regs *ctx) 97 { 98 unsigned int size = PT_REGS_PARM1(ctx); 99 100 /* verify malloc size */ 101 if (size == 1) 102 uprobe_byname2_res = 7; 103 return 0; 104 } 105 106 SEC("uretprobe") 107 int handle_uretprobe_byname2(struct pt_regs *ctx) 108 { 109 uretprobe_byname2_res = 8; 110 return 0; 111 } 112 113 static __always_inline bool verify_sleepable_user_copy(void) 114 { 115 char data[9]; 116 117 bpf_copy_from_user(data, sizeof(data), user_ptr); 118 return bpf_strncmp(data, sizeof(data), "test_data") == 0; 119 } 120 121 SEC("uprobe.s//proc/self/exe:trigger_func3") 122 int handle_uprobe_byname3_sleepable(struct pt_regs *ctx) 123 { 124 if (verify_sleepable_user_copy()) 125 uprobe_byname3_sleepable_res = 9; 126 return 0; 127 } 128 129 /** 130 * same target as the uprobe.s above to force sleepable and non-sleepable 131 * programs in the same bpf_prog_array 132 */ 133 SEC("uprobe//proc/self/exe:trigger_func3") 134 int handle_uprobe_byname3(struct pt_regs *ctx) 135 { 136 uprobe_byname3_res = 10; 137 return 0; 138 } 139 140 SEC("uretprobe.s//proc/self/exe:trigger_func3") 141 int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx) 142 { 143 if (verify_sleepable_user_copy()) 144 uretprobe_byname3_sleepable_res = 11; 145 return 0; 146 } 147 148 SEC("uretprobe//proc/self/exe:trigger_func3") 149 int handle_uretprobe_byname3(struct pt_regs *ctx) 150 { 151 uretprobe_byname3_res = 12; 152 return 0; 153 } 154 155 156 char _license[] SEC("license") = "GPL"; 157