kprobe_event_gen_test.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Test module for in-kernel kprobe event creation and generation.
  4. *
  5. * Copyright (C) 2019 Tom Zanussi <[email protected]>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/trace_events.h>
  9. /*
  10. * This module is a simple test of basic functionality for in-kernel
  11. * kprobe/kretprobe event creation. The first test uses
  12. * kprobe_event_gen_cmd_start(), kprobe_event_add_fields() and
  13. * kprobe_event_gen_cmd_end() to create a kprobe event, which is then
  14. * enabled in order to generate trace output. The second creates a
  15. * kretprobe event using kretprobe_event_gen_cmd_start() and
  16. * kretprobe_event_gen_cmd_end(), and is also then enabled.
  17. *
  18. * To test, select CONFIG_KPROBE_EVENT_GEN_TEST and build the module.
  19. * Then:
  20. *
  21. * # insmod kernel/trace/kprobe_event_gen_test.ko
  22. * # cat /sys/kernel/debug/tracing/trace
  23. *
  24. * You should see many instances of the "gen_kprobe_test" and
  25. * "gen_kretprobe_test" events in the trace buffer.
  26. *
  27. * To remove the events, remove the module:
  28. *
  29. * # rmmod kprobe_event_gen_test
  30. *
  31. */
  32. static struct trace_event_file *gen_kprobe_test;
  33. static struct trace_event_file *gen_kretprobe_test;
  34. #define KPROBE_GEN_TEST_FUNC "do_sys_open"
  35. /* X86 */
  36. #if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
  37. #define KPROBE_GEN_TEST_ARG0 "dfd=%ax"
  38. #define KPROBE_GEN_TEST_ARG1 "filename=%dx"
  39. #define KPROBE_GEN_TEST_ARG2 "flags=%cx"
  40. #define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)"
  41. /* ARM64 */
  42. #elif defined(CONFIG_ARM64)
  43. #define KPROBE_GEN_TEST_ARG0 "dfd=%x0"
  44. #define KPROBE_GEN_TEST_ARG1 "filename=%x1"
  45. #define KPROBE_GEN_TEST_ARG2 "flags=%x2"
  46. #define KPROBE_GEN_TEST_ARG3 "mode=%x3"
  47. /* ARM */
  48. #elif defined(CONFIG_ARM)
  49. #define KPROBE_GEN_TEST_ARG0 "dfd=%r0"
  50. #define KPROBE_GEN_TEST_ARG1 "filename=%r1"
  51. #define KPROBE_GEN_TEST_ARG2 "flags=%r2"
  52. #define KPROBE_GEN_TEST_ARG3 "mode=%r3"
  53. /* RISCV */
  54. #elif defined(CONFIG_RISCV)
  55. #define KPROBE_GEN_TEST_ARG0 "dfd=%a0"
  56. #define KPROBE_GEN_TEST_ARG1 "filename=%a1"
  57. #define KPROBE_GEN_TEST_ARG2 "flags=%a2"
  58. #define KPROBE_GEN_TEST_ARG3 "mode=%a3"
  59. /* others */
  60. #else
  61. #define KPROBE_GEN_TEST_ARG0 NULL
  62. #define KPROBE_GEN_TEST_ARG1 NULL
  63. #define KPROBE_GEN_TEST_ARG2 NULL
  64. #define KPROBE_GEN_TEST_ARG3 NULL
  65. #endif
  66. static bool trace_event_file_is_valid(struct trace_event_file *input)
  67. {
  68. return input && !IS_ERR(input);
  69. }
  70. /*
  71. * Test to make sure we can create a kprobe event, then add more
  72. * fields.
  73. */
  74. static int __init test_gen_kprobe_cmd(void)
  75. {
  76. struct dynevent_cmd cmd;
  77. char *buf;
  78. int ret;
  79. /* Create a buffer to hold the generated command */
  80. buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
  81. if (!buf)
  82. return -ENOMEM;
  83. /* Before generating the command, initialize the cmd object */
  84. kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
  85. /*
  86. * Define the gen_kprobe_test event with the first 2 kprobe
  87. * fields.
  88. */
  89. ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
  90. KPROBE_GEN_TEST_FUNC,
  91. KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
  92. if (ret)
  93. goto out;
  94. /* Use kprobe_event_add_fields to add the rest of the fields */
  95. ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
  96. if (ret)
  97. goto out;
  98. /*
  99. * This actually creates the event.
  100. */
  101. ret = kprobe_event_gen_cmd_end(&cmd);
  102. if (ret)
  103. goto out;
  104. /*
  105. * Now get the gen_kprobe_test event file. We need to prevent
  106. * the instance and event from disappearing from underneath
  107. * us, which trace_get_event_file() does (though in this case
  108. * we're using the top-level instance which never goes away).
  109. */
  110. gen_kprobe_test = trace_get_event_file(NULL, "kprobes",
  111. "gen_kprobe_test");
  112. if (IS_ERR(gen_kprobe_test)) {
  113. ret = PTR_ERR(gen_kprobe_test);
  114. goto delete;
  115. }
  116. /* Enable the event or you won't see anything */
  117. ret = trace_array_set_clr_event(gen_kprobe_test->tr,
  118. "kprobes", "gen_kprobe_test", true);
  119. if (ret) {
  120. trace_put_event_file(gen_kprobe_test);
  121. goto delete;
  122. }
  123. out:
  124. kfree(buf);
  125. return ret;
  126. delete:
  127. if (trace_event_file_is_valid(gen_kprobe_test))
  128. gen_kprobe_test = NULL;
  129. /* We got an error after creating the event, delete it */
  130. kprobe_event_delete("gen_kprobe_test");
  131. goto out;
  132. }
  133. /*
  134. * Test to make sure we can create a kretprobe event.
  135. */
  136. static int __init test_gen_kretprobe_cmd(void)
  137. {
  138. struct dynevent_cmd cmd;
  139. char *buf;
  140. int ret;
  141. /* Create a buffer to hold the generated command */
  142. buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
  143. if (!buf)
  144. return -ENOMEM;
  145. /* Before generating the command, initialize the cmd object */
  146. kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
  147. /*
  148. * Define the kretprobe event.
  149. */
  150. ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
  151. KPROBE_GEN_TEST_FUNC,
  152. "$retval");
  153. if (ret)
  154. goto out;
  155. /*
  156. * This actually creates the event.
  157. */
  158. ret = kretprobe_event_gen_cmd_end(&cmd);
  159. if (ret)
  160. goto out;
  161. /*
  162. * Now get the gen_kretprobe_test event file. We need to
  163. * prevent the instance and event from disappearing from
  164. * underneath us, which trace_get_event_file() does (though in
  165. * this case we're using the top-level instance which never
  166. * goes away).
  167. */
  168. gen_kretprobe_test = trace_get_event_file(NULL, "kprobes",
  169. "gen_kretprobe_test");
  170. if (IS_ERR(gen_kretprobe_test)) {
  171. ret = PTR_ERR(gen_kretprobe_test);
  172. goto delete;
  173. }
  174. /* Enable the event or you won't see anything */
  175. ret = trace_array_set_clr_event(gen_kretprobe_test->tr,
  176. "kprobes", "gen_kretprobe_test", true);
  177. if (ret) {
  178. trace_put_event_file(gen_kretprobe_test);
  179. goto delete;
  180. }
  181. out:
  182. kfree(buf);
  183. return ret;
  184. delete:
  185. if (trace_event_file_is_valid(gen_kretprobe_test))
  186. gen_kretprobe_test = NULL;
  187. /* We got an error after creating the event, delete it */
  188. kprobe_event_delete("gen_kretprobe_test");
  189. goto out;
  190. }
  191. static int __init kprobe_event_gen_test_init(void)
  192. {
  193. int ret;
  194. ret = test_gen_kprobe_cmd();
  195. if (ret)
  196. return ret;
  197. ret = test_gen_kretprobe_cmd();
  198. if (ret) {
  199. if (trace_event_file_is_valid(gen_kretprobe_test)) {
  200. WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
  201. "kprobes",
  202. "gen_kretprobe_test", false));
  203. trace_put_event_file(gen_kretprobe_test);
  204. }
  205. WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
  206. }
  207. return ret;
  208. }
  209. static void __exit kprobe_event_gen_test_exit(void)
  210. {
  211. if (trace_event_file_is_valid(gen_kprobe_test)) {
  212. /* Disable the event or you can't remove it */
  213. WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
  214. "kprobes",
  215. "gen_kprobe_test", false));
  216. /* Now give the file and instance back */
  217. trace_put_event_file(gen_kprobe_test);
  218. }
  219. /* Now unregister and free the event */
  220. WARN_ON(kprobe_event_delete("gen_kprobe_test"));
  221. if (trace_event_file_is_valid(gen_kretprobe_test)) {
  222. /* Disable the event or you can't remove it */
  223. WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
  224. "kprobes",
  225. "gen_kretprobe_test", false));
  226. /* Now give the file and instance back */
  227. trace_put_event_file(gen_kretprobe_test);
  228. }
  229. /* Now unregister and free the event */
  230. WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
  231. }
  232. module_init(kprobe_event_gen_test_init)
  233. module_exit(kprobe_event_gen_test_exit)
  234. MODULE_AUTHOR("Tom Zanussi");
  235. MODULE_DESCRIPTION("kprobe event generation test");
  236. MODULE_LICENSE("GPL v2");