1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * fprobe - Simple ftrace probe wrapper for function entry. 4 */ 5 #define pr_fmt(fmt) "fprobe: " fmt 6 7 #include <linux/err.h> 8 #include <linux/fprobe.h> 9 #include <linux/kallsyms.h> 10 #include <linux/kprobes.h> 11 #include <linux/rethook.h> 12 #include <linux/slab.h> 13 #include <linux/sort.h> 14 15 #include "trace.h" 16 17 struct fprobe_rethook_node { 18 struct rethook_node node; 19 unsigned long entry_ip; 20 }; 21 22 static void fprobe_handler(unsigned long ip, unsigned long parent_ip, 23 struct ftrace_ops *ops, struct ftrace_regs *fregs) 24 { 25 struct fprobe_rethook_node *fpr; 26 struct rethook_node *rh; 27 struct fprobe *fp; 28 int bit; 29 30 fp = container_of(ops, struct fprobe, ops); 31 if (fprobe_disabled(fp)) 32 return; 33 34 bit = ftrace_test_recursion_trylock(ip, parent_ip); 35 if (bit < 0) { 36 fp->nmissed++; 37 return; 38 } 39 40 if (fp->entry_handler) 41 fp->entry_handler(fp, ip, ftrace_get_regs(fregs)); 42 43 if (fp->exit_handler) { 44 rh = rethook_try_get(fp->rethook); 45 if (!rh) { 46 fp->nmissed++; 47 goto out; 48 } 49 fpr = container_of(rh, struct fprobe_rethook_node, node); 50 fpr->entry_ip = ip; 51 rethook_hook(rh, ftrace_get_regs(fregs), true); 52 } 53 54 out: 55 ftrace_test_recursion_unlock(bit); 56 } 57 NOKPROBE_SYMBOL(fprobe_handler); 58 59 static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip, 60 struct ftrace_ops *ops, struct ftrace_regs *fregs) 61 { 62 struct fprobe *fp = container_of(ops, struct fprobe, ops); 63 64 if (unlikely(kprobe_running())) { 65 fp->nmissed++; 66 return; 67 } 68 kprobe_busy_begin(); 69 fprobe_handler(ip, parent_ip, ops, fregs); 70 kprobe_busy_end(); 71 } 72 73 static void fprobe_exit_handler(struct rethook_node *rh, void *data, 74 struct pt_regs *regs) 75 { 76 struct fprobe *fp = (struct fprobe *)data; 77 struct fprobe_rethook_node *fpr; 78 79 if (!fp || fprobe_disabled(fp)) 80 return; 81 82 fpr = container_of(rh, struct fprobe_rethook_node, node); 83 84 fp->exit_handler(fp, fpr->entry_ip, regs); 85 } 86 NOKPROBE_SYMBOL(fprobe_exit_handler); 87 88 /* Convert ftrace location address from symbols */ 89 static unsigned long *get_ftrace_locations(const char **syms, int num) 90 { 91 unsigned long addr, size; 92 unsigned long *addrs; 93 int i; 94 95 /* Convert symbols to symbol address */ 96 addrs = kcalloc(num, sizeof(*addrs), GFP_KERNEL); 97 if (!addrs) 98 return ERR_PTR(-ENOMEM); 99 100 for (i = 0; i < num; i++) { 101 addr = kallsyms_lookup_name(syms[i]); 102 if (!addr) /* Maybe wrong symbol */ 103 goto error; 104 105 /* Convert symbol address to ftrace location. */ 106 if (!kallsyms_lookup_size_offset(addr, &size, NULL) || !size) 107 goto error; 108 109 addr = ftrace_location_range(addr, addr + size - 1); 110 if (!addr) /* No dynamic ftrace there. */ 111 goto error; 112 113 addrs[i] = addr; 114 } 115 116 return addrs; 117 118 error: 119 kfree(addrs); 120 121 return ERR_PTR(-ENOENT); 122 } 123 124 static void fprobe_init(struct fprobe *fp) 125 { 126 fp->nmissed = 0; 127 if (fprobe_shared_with_kprobes(fp)) 128 fp->ops.func = fprobe_kprobe_handler; 129 else 130 fp->ops.func = fprobe_handler; 131 fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS; 132 } 133 134 static int fprobe_init_rethook(struct fprobe *fp, int num) 135 { 136 int i, size; 137 138 if (num < 0) 139 return -EINVAL; 140 141 if (!fp->exit_handler) { 142 fp->rethook = NULL; 143 return 0; 144 } 145 146 /* Initialize rethook if needed */ 147 size = num * num_possible_cpus() * 2; 148 if (size < 0) 149 return -E2BIG; 150 151 fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); 152 for (i = 0; i < size; i++) { 153 struct fprobe_rethook_node *node; 154 155 node = kzalloc(sizeof(*node), GFP_KERNEL); 156 if (!node) { 157 rethook_free(fp->rethook); 158 fp->rethook = NULL; 159 return -ENOMEM; 160 } 161 rethook_add_node(fp->rethook, &node->node); 162 } 163 return 0; 164 } 165 166 static void fprobe_fail_cleanup(struct fprobe *fp) 167 { 168 if (fp->rethook) { 169 /* Don't need to cleanup rethook->handler because this is not used. */ 170 rethook_free(fp->rethook); 171 fp->rethook = NULL; 172 } 173 ftrace_free_filter(&fp->ops); 174 } 175 176 /** 177 * register_fprobe() - Register fprobe to ftrace by pattern. 178 * @fp: A fprobe data structure to be registered. 179 * @filter: A wildcard pattern of probed symbols. 180 * @notfilter: A wildcard pattern of NOT probed symbols. 181 * 182 * Register @fp to ftrace for enabling the probe on the symbols matched to @filter. 183 * If @notfilter is not NULL, the symbols matched the @notfilter are not probed. 184 * 185 * Return 0 if @fp is registered successfully, -errno if not. 186 */ 187 int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) 188 { 189 struct ftrace_hash *hash; 190 unsigned char *str; 191 int ret, len; 192 193 if (!fp || !filter) 194 return -EINVAL; 195 196 fprobe_init(fp); 197 198 len = strlen(filter); 199 str = kstrdup(filter, GFP_KERNEL); 200 ret = ftrace_set_filter(&fp->ops, str, len, 0); 201 kfree(str); 202 if (ret) 203 return ret; 204 205 if (notfilter) { 206 len = strlen(notfilter); 207 str = kstrdup(notfilter, GFP_KERNEL); 208 ret = ftrace_set_notrace(&fp->ops, str, len, 0); 209 kfree(str); 210 if (ret) 211 goto out; 212 } 213 214 /* TODO: 215 * correctly calculate the total number of filtered symbols 216 * from both filter and notfilter. 217 */ 218 hash = rcu_access_pointer(fp->ops.local_hash.filter_hash); 219 if (WARN_ON_ONCE(!hash)) 220 goto out; 221 222 ret = fprobe_init_rethook(fp, (int)hash->count); 223 if (!ret) 224 ret = register_ftrace_function(&fp->ops); 225 226 out: 227 if (ret) 228 fprobe_fail_cleanup(fp); 229 return ret; 230 } 231 EXPORT_SYMBOL_GPL(register_fprobe); 232 233 /** 234 * register_fprobe_ips() - Register fprobe to ftrace by address. 235 * @fp: A fprobe data structure to be registered. 236 * @addrs: An array of target ftrace location addresses. 237 * @num: The number of entries of @addrs. 238 * 239 * Register @fp to ftrace for enabling the probe on the address given by @addrs. 240 * The @addrs must be the addresses of ftrace location address, which may be 241 * the symbol address + arch-dependent offset. 242 * If you unsure what this mean, please use other registration functions. 243 * 244 * Return 0 if @fp is registered successfully, -errno if not. 245 */ 246 int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num) 247 { 248 int ret; 249 250 if (!fp || !addrs || num <= 0) 251 return -EINVAL; 252 253 fprobe_init(fp); 254 255 ret = ftrace_set_filter_ips(&fp->ops, addrs, num, 0, 0); 256 if (ret) 257 return ret; 258 259 ret = fprobe_init_rethook(fp, num); 260 if (!ret) 261 ret = register_ftrace_function(&fp->ops); 262 263 if (ret) 264 fprobe_fail_cleanup(fp); 265 return ret; 266 } 267 EXPORT_SYMBOL_GPL(register_fprobe_ips); 268 269 /** 270 * register_fprobe_syms() - Register fprobe to ftrace by symbols. 271 * @fp: A fprobe data structure to be registered. 272 * @syms: An array of target symbols. 273 * @num: The number of entries of @syms. 274 * 275 * Register @fp to the symbols given by @syms array. This will be useful if 276 * you are sure the symbols exist in the kernel. 277 * 278 * Return 0 if @fp is registered successfully, -errno if not. 279 */ 280 int register_fprobe_syms(struct fprobe *fp, const char **syms, int num) 281 { 282 unsigned long *addrs; 283 int ret; 284 285 if (!fp || !syms || num <= 0) 286 return -EINVAL; 287 288 addrs = get_ftrace_locations(syms, num); 289 if (IS_ERR(addrs)) 290 return PTR_ERR(addrs); 291 292 ret = register_fprobe_ips(fp, addrs, num); 293 294 kfree(addrs); 295 296 return ret; 297 } 298 EXPORT_SYMBOL_GPL(register_fprobe_syms); 299 300 /** 301 * unregister_fprobe() - Unregister fprobe from ftrace 302 * @fp: A fprobe data structure to be unregistered. 303 * 304 * Unregister fprobe (and remove ftrace hooks from the function entries). 305 * 306 * Return 0 if @fp is unregistered successfully, -errno if not. 307 */ 308 int unregister_fprobe(struct fprobe *fp) 309 { 310 int ret; 311 312 if (!fp || fp->ops.func != fprobe_handler) 313 return -EINVAL; 314 315 /* 316 * rethook_free() starts disabling the rethook, but the rethook handlers 317 * may be running on other processors at this point. To make sure that all 318 * current running handlers are finished, call unregister_ftrace_function() 319 * after this. 320 */ 321 if (fp->rethook) 322 rethook_free(fp->rethook); 323 324 ret = unregister_ftrace_function(&fp->ops); 325 if (ret < 0) 326 return ret; 327 328 ftrace_free_filter(&fp->ops); 329 330 return ret; 331 } 332 EXPORT_SYMBOL_GPL(unregister_fprobe); 333