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