test_kprobes.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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. kp.addr = 0; /* addr should be cleard for reusing kprobe. */
  100. ret = register_kprobes(kps, 2);
  101. if (ret < 0) {
  102. printk(KERN_ERR "Kprobe smoke test failed: "
  103. "register_kprobes returned %d\n", ret);
  104. return ret;
  105. }
  106. preh_val = 0;
  107. posth_val = 0;
  108. ret = target(rand1);
  109. if (preh_val == 0) {
  110. printk(KERN_ERR "Kprobe smoke test failed: "
  111. "kprobe pre_handler not called\n");
  112. handler_errors++;
  113. }
  114. if (posth_val == 0) {
  115. printk(KERN_ERR "Kprobe smoke test failed: "
  116. "kprobe post_handler not called\n");
  117. handler_errors++;
  118. }
  119. preh_val = 0;
  120. posth_val = 0;
  121. ret = target2(rand1);
  122. if (preh_val == 0) {
  123. printk(KERN_ERR "Kprobe smoke test failed: "
  124. "kprobe pre_handler2 not called\n");
  125. handler_errors++;
  126. }
  127. if (posth_val == 0) {
  128. printk(KERN_ERR "Kprobe smoke test failed: "
  129. "kprobe post_handler2 not called\n");
  130. handler_errors++;
  131. }
  132. unregister_kprobes(kps, 2);
  133. return 0;
  134. }
  135. static u32 j_kprobe_target(u32 value)
  136. {
  137. if (value != rand1) {
  138. handler_errors++;
  139. printk(KERN_ERR "Kprobe smoke test failed: "
  140. "incorrect value in jprobe handler\n");
  141. }
  142. jph_val = rand1;
  143. jprobe_return();
  144. return 0;
  145. }
  146. static struct jprobe jp = {
  147. .entry = j_kprobe_target,
  148. .kp.symbol_name = "kprobe_target"
  149. };
  150. static int test_jprobe(void)
  151. {
  152. int ret;
  153. ret = register_jprobe(&jp);
  154. if (ret < 0) {
  155. printk(KERN_ERR "Kprobe smoke test failed: "
  156. "register_jprobe returned %d\n", ret);
  157. return ret;
  158. }
  159. ret = target(rand1);
  160. unregister_jprobe(&jp);
  161. if (jph_val == 0) {
  162. printk(KERN_ERR "Kprobe smoke test failed: "
  163. "jprobe handler not called\n");
  164. handler_errors++;
  165. }
  166. return 0;
  167. }
  168. static struct jprobe jp2 = {
  169. .entry = j_kprobe_target,
  170. .kp.symbol_name = "kprobe_target2"
  171. };
  172. static int test_jprobes(void)
  173. {
  174. int ret;
  175. struct jprobe *jps[2] = {&jp, &jp2};
  176. jp.kp.addr = 0; /* addr should be cleard for reusing kprobe. */
  177. ret = register_jprobes(jps, 2);
  178. if (ret < 0) {
  179. printk(KERN_ERR "Kprobe smoke test failed: "
  180. "register_jprobes returned %d\n", ret);
  181. return ret;
  182. }
  183. jph_val = 0;
  184. ret = target(rand1);
  185. if (jph_val == 0) {
  186. printk(KERN_ERR "Kprobe smoke test failed: "
  187. "jprobe handler not called\n");
  188. handler_errors++;
  189. }
  190. jph_val = 0;
  191. ret = target2(rand1);
  192. if (jph_val == 0) {
  193. printk(KERN_ERR "Kprobe smoke test failed: "
  194. "jprobe handler2 not called\n");
  195. handler_errors++;
  196. }
  197. unregister_jprobes(jps, 2);
  198. return 0;
  199. }
  200. #ifdef CONFIG_KRETPROBES
  201. static u32 krph_val;
  202. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  203. {
  204. krph_val = (rand1 / div_factor);
  205. return 0;
  206. }
  207. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  208. {
  209. unsigned long ret = regs_return_value(regs);
  210. if (ret != (rand1 / div_factor)) {
  211. handler_errors++;
  212. printk(KERN_ERR "Kprobe smoke test failed: "
  213. "incorrect value in kretprobe handler\n");
  214. }
  215. if (krph_val == 0) {
  216. handler_errors++;
  217. printk(KERN_ERR "Kprobe smoke test failed: "
  218. "call to kretprobe entry handler failed\n");
  219. }
  220. krph_val = rand1;
  221. return 0;
  222. }
  223. static struct kretprobe rp = {
  224. .handler = return_handler,
  225. .entry_handler = entry_handler,
  226. .kp.symbol_name = "kprobe_target"
  227. };
  228. static int test_kretprobe(void)
  229. {
  230. int ret;
  231. ret = register_kretprobe(&rp);
  232. if (ret < 0) {
  233. printk(KERN_ERR "Kprobe smoke test failed: "
  234. "register_kretprobe returned %d\n", ret);
  235. return ret;
  236. }
  237. ret = target(rand1);
  238. unregister_kretprobe(&rp);
  239. if (krph_val != rand1) {
  240. printk(KERN_ERR "Kprobe smoke test failed: "
  241. "kretprobe handler not called\n");
  242. handler_errors++;
  243. }
  244. return 0;
  245. }
  246. static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
  247. {
  248. unsigned long ret = regs_return_value(regs);
  249. if (ret != (rand1 / div_factor) + 1) {
  250. handler_errors++;
  251. printk(KERN_ERR "Kprobe smoke test failed: "
  252. "incorrect value in kretprobe handler2\n");
  253. }
  254. if (krph_val == 0) {
  255. handler_errors++;
  256. printk(KERN_ERR "Kprobe smoke test failed: "
  257. "call to kretprobe entry handler failed\n");
  258. }
  259. krph_val = rand1;
  260. return 0;
  261. }
  262. static struct kretprobe rp2 = {
  263. .handler = return_handler2,
  264. .entry_handler = entry_handler,
  265. .kp.symbol_name = "kprobe_target2"
  266. };
  267. static int test_kretprobes(void)
  268. {
  269. int ret;
  270. struct kretprobe *rps[2] = {&rp, &rp2};
  271. rp.kp.addr = 0; /* addr should be cleard for reusing kprobe. */
  272. ret = register_kretprobes(rps, 2);
  273. if (ret < 0) {
  274. printk(KERN_ERR "Kprobe smoke test failed: "
  275. "register_kretprobe returned %d\n", ret);
  276. return ret;
  277. }
  278. krph_val = 0;
  279. ret = target(rand1);
  280. if (krph_val != rand1) {
  281. printk(KERN_ERR "Kprobe smoke test failed: "
  282. "kretprobe handler not called\n");
  283. handler_errors++;
  284. }
  285. krph_val = 0;
  286. ret = target2(rand1);
  287. if (krph_val != rand1) {
  288. printk(KERN_ERR "Kprobe smoke test failed: "
  289. "kretprobe handler2 not called\n");
  290. handler_errors++;
  291. }
  292. unregister_kretprobes(rps, 2);
  293. return 0;
  294. }
  295. #endif /* CONFIG_KRETPROBES */
  296. int init_test_probes(void)
  297. {
  298. int ret;
  299. target = kprobe_target;
  300. target2 = kprobe_target2;
  301. do {
  302. rand1 = random32();
  303. } while (rand1 <= div_factor);
  304. printk(KERN_INFO "Kprobe smoke test started\n");
  305. num_tests++;
  306. ret = test_kprobe();
  307. if (ret < 0)
  308. errors++;
  309. num_tests++;
  310. ret = test_kprobes();
  311. if (ret < 0)
  312. errors++;
  313. num_tests++;
  314. ret = test_jprobe();
  315. if (ret < 0)
  316. errors++;
  317. num_tests++;
  318. ret = test_jprobes();
  319. if (ret < 0)
  320. errors++;
  321. #ifdef CONFIG_KRETPROBES
  322. num_tests++;
  323. ret = test_kretprobe();
  324. if (ret < 0)
  325. errors++;
  326. num_tests++;
  327. ret = test_kretprobes();
  328. if (ret < 0)
  329. errors++;
  330. #endif /* CONFIG_KRETPROBES */
  331. if (errors)
  332. printk(KERN_ERR "BUG: Kprobe smoke test: %d out of "
  333. "%d tests failed\n", errors, num_tests);
  334. else if (handler_errors)
  335. printk(KERN_ERR "BUG: Kprobe smoke test: %d error(s) "
  336. "running handlers\n", handler_errors);
  337. else
  338. printk(KERN_INFO "Kprobe smoke test passed successfully\n");
  339. return 0;
  340. }