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