fprobe.c 7.6 KB

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