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