test_kprobes.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. * test_kprobes.c - simple sanity test for *probes
  3. *
  4. * Copyright IBM Corp. 2008
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it would be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  14. * the GNU General Public License for more details.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/kprobes.h>
  18. #include <linux/random.h>
  19. #define div_factor 3
  20. static u32 rand1, preh_val, posth_val, jph_val;
  21. static int errors, handler_errors, num_tests;
  22. static u32 (*target)(u32 value);
  23. static u32 (*target2)(u32 value);
  24. static noinline u32 kprobe_target(u32 value)
  25. {
  26. return (value / div_factor);
  27. }
  28. static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
  29. {
  30. preh_val = (rand1 / div_factor);
  31. return 0;
  32. }
  33. static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
  34. unsigned long flags)
  35. {
  36. if (preh_val != (rand1 / div_factor)) {
  37. handler_errors++;
  38. printk(KERN_ERR "Kprobe smoke test failed: "
  39. "incorrect value in post_handler\n");
  40. }
  41. posth_val = preh_val + div_factor;
  42. }
  43. static struct kprobe kp = {
  44. .symbol_name = "kprobe_target",
  45. .pre_handler = kp_pre_handler,
  46. .post_handler = kp_post_handler
  47. };
  48. static int test_kprobe(void)
  49. {
  50. int ret;
  51. ret = register_kprobe(&kp);
  52. if (ret < 0) {
  53. printk(KERN_ERR "Kprobe smoke test failed: "
  54. "register_kprobe returned %d\n", ret);
  55. return ret;
  56. }
  57. ret = target(rand1);
  58. unregister_kprobe(&kp);
  59. if (preh_val == 0) {
  60. printk(KERN_ERR "Kprobe smoke test failed: "
  61. "kprobe pre_handler not called\n");
  62. handler_errors++;
  63. }
  64. if (posth_val == 0) {
  65. printk(KERN_ERR "Kprobe smoke test failed: "
  66. "kprobe post_handler not called\n");
  67. handler_errors++;
  68. }
  69. return 0;
  70. }
  71. static noinline u32 kprobe_target2(u32 value)
  72. {
  73. return (value / div_factor) + 1;
  74. }
  75. static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
  76. {
  77. preh_val = (rand1 / div_factor) + 1;
  78. return 0;
  79. }
  80. static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
  81. unsigned long flags)
  82. {
  83. if (preh_val != (rand1 / div_factor) + 1) {
  84. handler_errors++;
  85. printk(KERN_ERR "Kprobe smoke test failed: "
  86. "incorrect value in post_handler2\n");
  87. }
  88. posth_val = preh_val + div_factor;
  89. }
  90. static struct kprobe kp2 = {
  91. .symbol_name = "kprobe_target2",
  92. .pre_handler = kp_pre_handler2,
  93. .post_handler = kp_post_handler2
  94. };
  95. static int test_kprobes(void)
  96. {
  97. int ret;
  98. struct kprobe *kps[2] = {&kp, &kp2};
  99. /* addr and flags should be cleard for reusing kprobe. */
  100. kp.addr = NULL;
  101. kp.flags = 0;
  102. ret = register_kprobes(kps, 2);
  103. if (ret < 0) {
  104. printk(KERN_ERR "Kprobe smoke test failed: "
  105. "register_kprobes returned %d\n", ret);
  106. return ret;
  107. }
  108. preh_val = 0;
  109. posth_val = 0;
  110. ret = target(rand1);
  111. if (preh_val == 0) {
  112. printk(KERN_ERR "Kprobe smoke test failed: "
  113. "kprobe pre_handler not called\n");
  114. handler_errors++;
  115. }
  116. if (posth_val == 0) {
  117. printk(KERN_ERR "Kprobe smoke test failed: "
  118. "kprobe post_handler not called\n");
  119. handler_errors++;
  120. }
  121. preh_val = 0;
  122. posth_val = 0;
  123. ret = target2(rand1);
  124. if (preh_val == 0) {
  125. printk(KERN_ERR "Kprobe smoke test failed: "
  126. "kprobe pre_handler2 not called\n");
  127. handler_errors++;
  128. }
  129. if (posth_val == 0) {
  130. printk(KERN_ERR "Kprobe smoke test failed: "
  131. "kprobe post_handler2 not called\n");
  132. handler_errors++;
  133. }
  134. unregister_kprobes(kps, 2);
  135. return 0;
  136. }
  137. static u32 j_kprobe_target(u32 value)
  138. {
  139. if (value != rand1) {
  140. handler_errors++;
  141. printk(KERN_ERR "Kprobe smoke test failed: "
  142. "incorrect value in jprobe handler\n");
  143. }
  144. jph_val = rand1;
  145. jprobe_return();
  146. return 0;
  147. }
  148. static struct jprobe jp = {
  149. .entry = j_kprobe_target,
  150. .kp.symbol_name = "kprobe_target"
  151. };
  152. static int test_jprobe(void)
  153. {
  154. int ret;
  155. ret = register_jprobe(&jp);
  156. if (ret < 0) {
  157. printk(KERN_ERR "Kprobe smoke test failed: "
  158. "register_jprobe returned %d\n", ret);
  159. return ret;
  160. }
  161. ret = target(rand1);
  162. unregister_jprobe(&jp);
  163. if (jph_val == 0) {
  164. printk(KERN_ERR "Kprobe smoke test failed: "
  165. "jprobe handler not called\n");
  166. handler_errors++;
  167. }
  168. return 0;
  169. }
  170. static struct jprobe jp2 = {
  171. .entry = j_kprobe_target,
  172. .kp.symbol_name = "kprobe_target2"
  173. };
  174. static int test_jprobes(void)
  175. {
  176. int ret;
  177. struct jprobe *jps[2] = {&jp, &jp2};
  178. /* addr and flags should be cleard for reusing kprobe. */
  179. jp.kp.addr = NULL;
  180. jp.kp.flags = 0;
  181. ret = register_jprobes(jps, 2);
  182. if (ret < 0) {
  183. printk(KERN_ERR "Kprobe smoke test failed: "
  184. "register_jprobes returned %d\n", ret);
  185. return ret;
  186. }
  187. jph_val = 0;
  188. ret = target(rand1);
  189. if (jph_val == 0) {
  190. printk(KERN_ERR "Kprobe smoke test failed: "
  191. "jprobe handler not called\n");
  192. handler_errors++;
  193. }
  194. jph_val = 0;
  195. ret = target2(rand1);
  196. if (jph_val == 0) {
  197. printk(KERN_ERR "Kprobe smoke test failed: "
  198. "jprobe handler2 not called\n");
  199. handler_errors++;
  200. }
  201. unregister_jprobes(jps, 2);
  202. return 0;
  203. }
  204. #ifdef CONFIG_KRETPROBES
  205. static u32 krph_val;
  206. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  207. {
  208. krph_val = (rand1 / div_factor);
  209. return 0;
  210. }
  211. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  212. {
  213. unsigned long ret = regs_return_value(regs);
  214. if (ret != (rand1 / div_factor)) {
  215. handler_errors++;
  216. printk(KERN_ERR "Kprobe smoke test failed: "
  217. "incorrect value in kretprobe handler\n");
  218. }
  219. if (krph_val == 0) {
  220. handler_errors++;
  221. printk(KERN_ERR "Kprobe smoke test failed: "
  222. "call to kretprobe entry handler failed\n");
  223. }
  224. krph_val = rand1;
  225. return 0;
  226. }
  227. static struct kretprobe rp = {
  228. .handler = return_handler,
  229. .entry_handler = entry_handler,
  230. .kp.symbol_name = "kprobe_target"
  231. };
  232. static int test_kretprobe(void)
  233. {
  234. int ret;
  235. ret = register_kretprobe(&rp);
  236. if (ret < 0) {
  237. printk(KERN_ERR "Kprobe smoke test failed: "
  238. "register_kretprobe returned %d\n", ret);
  239. return ret;
  240. }
  241. ret = target(rand1);
  242. unregister_kretprobe(&rp);
  243. if (krph_val != rand1) {
  244. printk(KERN_ERR "Kprobe smoke test failed: "
  245. "kretprobe handler not called\n");
  246. handler_errors++;
  247. }
  248. return 0;
  249. }
  250. static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
  251. {
  252. unsigned long ret = regs_return_value(regs);
  253. if (ret != (rand1 / div_factor) + 1) {
  254. handler_errors++;
  255. printk(KERN_ERR "Kprobe smoke test failed: "
  256. "incorrect value in kretprobe handler2\n");
  257. }
  258. if (krph_val == 0) {
  259. handler_errors++;
  260. printk(KERN_ERR "Kprobe smoke test failed: "
  261. "call to kretprobe entry handler failed\n");
  262. }
  263. krph_val = rand1;
  264. return 0;
  265. }
  266. static struct kretprobe rp2 = {
  267. .handler = return_handler2,
  268. .entry_handler = entry_handler,
  269. .kp.symbol_name = "kprobe_target2"
  270. };
  271. static int test_kretprobes(void)
  272. {
  273. int ret;
  274. struct kretprobe *rps[2] = {&rp, &rp2};
  275. /* addr and flags should be cleard for reusing kprobe. */
  276. rp.kp.addr = NULL;
  277. rp.kp.flags = 0;
  278. ret = register_kretprobes(rps, 2);
  279. if (ret < 0) {
  280. printk(KERN_ERR "Kprobe smoke test failed: "
  281. "register_kretprobe returned %d\n", ret);
  282. return ret;
  283. }
  284. krph_val = 0;
  285. ret = target(rand1);
  286. if (krph_val != rand1) {
  287. printk(KERN_ERR "Kprobe smoke test failed: "
  288. "kretprobe handler not called\n");
  289. handler_errors++;
  290. }
  291. krph_val = 0;
  292. ret = target2(rand1);
  293. if (krph_val != rand1) {
  294. printk(KERN_ERR "Kprobe smoke test failed: "
  295. "kretprobe handler2 not called\n");
  296. handler_errors++;
  297. }
  298. unregister_kretprobes(rps, 2);
  299. return 0;
  300. }
  301. #endif /* CONFIG_KRETPROBES */
  302. int init_test_probes(void)
  303. {
  304. int ret;
  305. target = kprobe_target;
  306. target2 = kprobe_target2;
  307. do {
  308. rand1 = random32();
  309. } while (rand1 <= div_factor);
  310. printk(KERN_INFO "Kprobe smoke test started\n");
  311. num_tests++;
  312. ret = test_kprobe();
  313. if (ret < 0)
  314. errors++;
  315. num_tests++;
  316. ret = test_kprobes();
  317. if (ret < 0)
  318. errors++;
  319. num_tests++;
  320. ret = test_jprobe();
  321. if (ret < 0)
  322. errors++;
  323. num_tests++;
  324. ret = test_jprobes();
  325. if (ret < 0)
  326. errors++;
  327. #ifdef CONFIG_KRETPROBES
  328. num_tests++;
  329. ret = test_kretprobe();
  330. if (ret < 0)
  331. errors++;
  332. num_tests++;
  333. ret = test_kretprobes();
  334. if (ret < 0)
  335. errors++;
  336. #endif /* CONFIG_KRETPROBES */
  337. if (errors)
  338. printk(KERN_ERR "BUG: Kprobe smoke test: %d out of "
  339. "%d tests failed\n", errors, num_tests);
  340. else if (handler_errors)
  341. printk(KERN_ERR "BUG: Kprobe smoke test: %d error(s) "
  342. "running handlers\n", handler_errors);
  343. else
  344. printk(KERN_INFO "Kprobe smoke test passed successfully\n");
  345. return 0;
  346. }