test_kprobes.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * test_kprobes.c - simple sanity test for *probes
  4. *
  5. * Copyright IBM Corp. 2008
  6. */
  7. #define pr_fmt(fmt) "Kprobe smoke test: " fmt
  8. #include <linux/kernel.h>
  9. #include <linux/kprobes.h>
  10. #include <linux/random.h>
  11. #define div_factor 3
  12. static u32 rand1, preh_val, posth_val;
  13. static int errors, handler_errors, num_tests;
  14. static u32 (*target)(u32 value);
  15. static u32 (*target2)(u32 value);
  16. static noinline u32 kprobe_target(u32 value)
  17. {
  18. return (value / div_factor);
  19. }
  20. static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
  21. {
  22. if (preemptible()) {
  23. handler_errors++;
  24. pr_err("pre-handler is preemptible\n");
  25. }
  26. preh_val = (rand1 / div_factor);
  27. return 0;
  28. }
  29. static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
  30. unsigned long flags)
  31. {
  32. if (preemptible()) {
  33. handler_errors++;
  34. pr_err("post-handler is preemptible\n");
  35. }
  36. if (preh_val != (rand1 / div_factor)) {
  37. handler_errors++;
  38. pr_err("incorrect value in post_handler\n");
  39. }
  40. posth_val = preh_val + div_factor;
  41. }
  42. static struct kprobe kp = {
  43. .symbol_name = "kprobe_target",
  44. .pre_handler = kp_pre_handler,
  45. .post_handler = kp_post_handler
  46. };
  47. static int test_kprobe(void)
  48. {
  49. int ret;
  50. ret = register_kprobe(&kp);
  51. if (ret < 0) {
  52. pr_err("register_kprobe returned %d\n", ret);
  53. return ret;
  54. }
  55. ret = target(rand1);
  56. unregister_kprobe(&kp);
  57. if (preh_val == 0) {
  58. pr_err("kprobe pre_handler not called\n");
  59. handler_errors++;
  60. }
  61. if (posth_val == 0) {
  62. pr_err("kprobe post_handler not called\n");
  63. handler_errors++;
  64. }
  65. return 0;
  66. }
  67. static noinline u32 kprobe_target2(u32 value)
  68. {
  69. return (value / div_factor) + 1;
  70. }
  71. static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
  72. {
  73. preh_val = (rand1 / div_factor) + 1;
  74. return 0;
  75. }
  76. static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
  77. unsigned long flags)
  78. {
  79. if (preh_val != (rand1 / div_factor) + 1) {
  80. handler_errors++;
  81. pr_err("incorrect value in post_handler2\n");
  82. }
  83. posth_val = preh_val + div_factor;
  84. }
  85. static struct kprobe kp2 = {
  86. .symbol_name = "kprobe_target2",
  87. .pre_handler = kp_pre_handler2,
  88. .post_handler = kp_post_handler2
  89. };
  90. static int test_kprobes(void)
  91. {
  92. int ret;
  93. struct kprobe *kps[2] = {&kp, &kp2};
  94. /* addr and flags should be cleard for reusing kprobe. */
  95. kp.addr = NULL;
  96. kp.flags = 0;
  97. ret = register_kprobes(kps, 2);
  98. if (ret < 0) {
  99. pr_err("register_kprobes returned %d\n", ret);
  100. return ret;
  101. }
  102. preh_val = 0;
  103. posth_val = 0;
  104. ret = target(rand1);
  105. if (preh_val == 0) {
  106. pr_err("kprobe pre_handler not called\n");
  107. handler_errors++;
  108. }
  109. if (posth_val == 0) {
  110. pr_err("kprobe post_handler not called\n");
  111. handler_errors++;
  112. }
  113. preh_val = 0;
  114. posth_val = 0;
  115. ret = target2(rand1);
  116. if (preh_val == 0) {
  117. pr_err("kprobe pre_handler2 not called\n");
  118. handler_errors++;
  119. }
  120. if (posth_val == 0) {
  121. pr_err("kprobe post_handler2 not called\n");
  122. handler_errors++;
  123. }
  124. unregister_kprobes(kps, 2);
  125. return 0;
  126. }
  127. #ifdef CONFIG_KRETPROBES
  128. static u32 krph_val;
  129. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  130. {
  131. if (preemptible()) {
  132. handler_errors++;
  133. pr_err("kretprobe entry handler is preemptible\n");
  134. }
  135. krph_val = (rand1 / div_factor);
  136. return 0;
  137. }
  138. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  139. {
  140. unsigned long ret = regs_return_value(regs);
  141. if (preemptible()) {
  142. handler_errors++;
  143. pr_err("kretprobe return handler is preemptible\n");
  144. }
  145. if (ret != (rand1 / div_factor)) {
  146. handler_errors++;
  147. pr_err("incorrect value in kretprobe handler\n");
  148. }
  149. if (krph_val == 0) {
  150. handler_errors++;
  151. pr_err("call to kretprobe entry handler failed\n");
  152. }
  153. krph_val = rand1;
  154. return 0;
  155. }
  156. static struct kretprobe rp = {
  157. .handler = return_handler,
  158. .entry_handler = entry_handler,
  159. .kp.symbol_name = "kprobe_target"
  160. };
  161. static int test_kretprobe(void)
  162. {
  163. int ret;
  164. ret = register_kretprobe(&rp);
  165. if (ret < 0) {
  166. pr_err("register_kretprobe returned %d\n", ret);
  167. return ret;
  168. }
  169. ret = target(rand1);
  170. unregister_kretprobe(&rp);
  171. if (krph_val != rand1) {
  172. pr_err("kretprobe handler not called\n");
  173. handler_errors++;
  174. }
  175. return 0;
  176. }
  177. static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
  178. {
  179. unsigned long ret = regs_return_value(regs);
  180. if (ret != (rand1 / div_factor) + 1) {
  181. handler_errors++;
  182. pr_err("incorrect value in kretprobe handler2\n");
  183. }
  184. if (krph_val == 0) {
  185. handler_errors++;
  186. pr_err("call to kretprobe entry handler failed\n");
  187. }
  188. krph_val = rand1;
  189. return 0;
  190. }
  191. static struct kretprobe rp2 = {
  192. .handler = return_handler2,
  193. .entry_handler = entry_handler,
  194. .kp.symbol_name = "kprobe_target2"
  195. };
  196. static int test_kretprobes(void)
  197. {
  198. int ret;
  199. struct kretprobe *rps[2] = {&rp, &rp2};
  200. /* addr and flags should be cleard for reusing kprobe. */
  201. rp.kp.addr = NULL;
  202. rp.kp.flags = 0;
  203. ret = register_kretprobes(rps, 2);
  204. if (ret < 0) {
  205. pr_err("register_kretprobe returned %d\n", ret);
  206. return ret;
  207. }
  208. krph_val = 0;
  209. ret = target(rand1);
  210. if (krph_val != rand1) {
  211. pr_err("kretprobe handler not called\n");
  212. handler_errors++;
  213. }
  214. krph_val = 0;
  215. ret = target2(rand1);
  216. if (krph_val != rand1) {
  217. pr_err("kretprobe handler2 not called\n");
  218. handler_errors++;
  219. }
  220. unregister_kretprobes(rps, 2);
  221. return 0;
  222. }
  223. #endif /* CONFIG_KRETPROBES */
  224. int init_test_probes(void)
  225. {
  226. int ret;
  227. target = kprobe_target;
  228. target2 = kprobe_target2;
  229. do {
  230. rand1 = prandom_u32();
  231. } while (rand1 <= div_factor);
  232. pr_info("started\n");
  233. num_tests++;
  234. ret = test_kprobe();
  235. if (ret < 0)
  236. errors++;
  237. num_tests++;
  238. ret = test_kprobes();
  239. if (ret < 0)
  240. errors++;
  241. #ifdef CONFIG_KRETPROBES
  242. num_tests++;
  243. ret = test_kretprobe();
  244. if (ret < 0)
  245. errors++;
  246. num_tests++;
  247. ret = test_kretprobes();
  248. if (ret < 0)
  249. errors++;
  250. #endif /* CONFIG_KRETPROBES */
  251. if (errors)
  252. pr_err("BUG: %d out of %d tests failed\n", errors, num_tests);
  253. else if (handler_errors)
  254. pr_err("BUG: %d error(s) running handlers\n", handler_errors);
  255. else
  256. pr_info("passed successfully\n");
  257. return 0;
  258. }