test-callbacks.sh 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. # Copyright (C) 2018 Joe Lawrence <[email protected]>
  4. . $(dirname $0)/functions.sh
  5. MOD_LIVEPATCH=test_klp_callbacks_demo
  6. MOD_LIVEPATCH2=test_klp_callbacks_demo2
  7. MOD_TARGET=test_klp_callbacks_mod
  8. MOD_TARGET_BUSY=test_klp_callbacks_busy
  9. setup_config
  10. # Test a combination of loading a kernel module and a livepatch that
  11. # patches a function in the first module. Load the target module
  12. # before the livepatch module. Unload them in the same order.
  13. #
  14. # - On livepatch enable, before the livepatch transition starts,
  15. # pre-patch callbacks are executed for vmlinux and $MOD_TARGET (those
  16. # klp_objects currently loaded). After klp_objects are patched
  17. # according to the klp_patch, their post-patch callbacks run and the
  18. # transition completes.
  19. #
  20. # - Similarly, on livepatch disable, pre-patch callbacks run before the
  21. # unpatching transition starts. klp_objects are reverted, post-patch
  22. # callbacks execute and the transition completes.
  23. start_test "target module before livepatch"
  24. load_mod $MOD_TARGET
  25. load_lp $MOD_LIVEPATCH
  26. disable_lp $MOD_LIVEPATCH
  27. unload_lp $MOD_LIVEPATCH
  28. unload_mod $MOD_TARGET
  29. check_result "% modprobe $MOD_TARGET
  30. $MOD_TARGET: ${MOD_TARGET}_init
  31. % modprobe $MOD_LIVEPATCH
  32. livepatch: enabling patch '$MOD_LIVEPATCH'
  33. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  34. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  35. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  36. livepatch: '$MOD_LIVEPATCH': starting patching transition
  37. livepatch: '$MOD_LIVEPATCH': completing patching transition
  38. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  39. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  40. livepatch: '$MOD_LIVEPATCH': patching complete
  41. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  42. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  43. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  44. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  45. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  46. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  47. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  48. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  49. livepatch: '$MOD_LIVEPATCH': unpatching complete
  50. % rmmod $MOD_LIVEPATCH
  51. % rmmod $MOD_TARGET
  52. $MOD_TARGET: ${MOD_TARGET}_exit"
  53. # This test is similar to the previous test, but (un)load the livepatch
  54. # module before the target kernel module. This tests the livepatch
  55. # core's module_coming handler.
  56. #
  57. # - On livepatch enable, only pre/post-patch callbacks are executed for
  58. # currently loaded klp_objects, in this case, vmlinux.
  59. #
  60. # - When a targeted module is subsequently loaded, only its
  61. # pre/post-patch callbacks are executed.
  62. #
  63. # - On livepatch disable, all currently loaded klp_objects' (vmlinux and
  64. # $MOD_TARGET) pre/post-unpatch callbacks are executed.
  65. start_test "module_coming notifier"
  66. load_lp $MOD_LIVEPATCH
  67. load_mod $MOD_TARGET
  68. disable_lp $MOD_LIVEPATCH
  69. unload_lp $MOD_LIVEPATCH
  70. unload_mod $MOD_TARGET
  71. check_result "% modprobe $MOD_LIVEPATCH
  72. livepatch: enabling patch '$MOD_LIVEPATCH'
  73. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  74. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  75. livepatch: '$MOD_LIVEPATCH': starting patching transition
  76. livepatch: '$MOD_LIVEPATCH': completing patching transition
  77. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  78. livepatch: '$MOD_LIVEPATCH': patching complete
  79. % modprobe $MOD_TARGET
  80. livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
  81. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  82. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  83. $MOD_TARGET: ${MOD_TARGET}_init
  84. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  85. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  86. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  87. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  88. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  89. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  90. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  91. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  92. livepatch: '$MOD_LIVEPATCH': unpatching complete
  93. % rmmod $MOD_LIVEPATCH
  94. % rmmod $MOD_TARGET
  95. $MOD_TARGET: ${MOD_TARGET}_exit"
  96. # Test loading the livepatch after a targeted kernel module, then unload
  97. # the kernel module before disabling the livepatch. This tests the
  98. # livepatch core's module_going handler.
  99. #
  100. # - First load a target module, then the livepatch.
  101. #
  102. # - When a target module is unloaded, the livepatch is only reverted
  103. # from that klp_object ($MOD_TARGET). As such, only its pre and
  104. # post-unpatch callbacks are executed when this occurs.
  105. #
  106. # - When the livepatch is disabled, pre and post-unpatch callbacks are
  107. # run for the remaining klp_object, vmlinux.
  108. start_test "module_going notifier"
  109. load_mod $MOD_TARGET
  110. load_lp $MOD_LIVEPATCH
  111. unload_mod $MOD_TARGET
  112. disable_lp $MOD_LIVEPATCH
  113. unload_lp $MOD_LIVEPATCH
  114. check_result "% modprobe $MOD_TARGET
  115. $MOD_TARGET: ${MOD_TARGET}_init
  116. % modprobe $MOD_LIVEPATCH
  117. livepatch: enabling patch '$MOD_LIVEPATCH'
  118. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  119. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  120. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  121. livepatch: '$MOD_LIVEPATCH': starting patching transition
  122. livepatch: '$MOD_LIVEPATCH': completing patching transition
  123. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  124. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
  125. livepatch: '$MOD_LIVEPATCH': patching complete
  126. % rmmod $MOD_TARGET
  127. $MOD_TARGET: ${MOD_TARGET}_exit
  128. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  129. livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
  130. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  131. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  132. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  133. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  134. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  135. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  136. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  137. livepatch: '$MOD_LIVEPATCH': unpatching complete
  138. % rmmod $MOD_LIVEPATCH"
  139. # This test is similar to the previous test, however the livepatch is
  140. # loaded first. This tests the livepatch core's module_coming and
  141. # module_going handlers.
  142. #
  143. # - First load the livepatch.
  144. #
  145. # - When a targeted kernel module is subsequently loaded, only its
  146. # pre/post-patch callbacks are executed.
  147. #
  148. # - When the target module is unloaded, the livepatch is only reverted
  149. # from the $MOD_TARGET klp_object. As such, only pre and
  150. # post-unpatch callbacks are executed when this occurs.
  151. start_test "module_coming and module_going notifiers"
  152. load_lp $MOD_LIVEPATCH
  153. load_mod $MOD_TARGET
  154. unload_mod $MOD_TARGET
  155. disable_lp $MOD_LIVEPATCH
  156. unload_lp $MOD_LIVEPATCH
  157. check_result "% modprobe $MOD_LIVEPATCH
  158. livepatch: enabling patch '$MOD_LIVEPATCH'
  159. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  160. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  161. livepatch: '$MOD_LIVEPATCH': starting patching transition
  162. livepatch: '$MOD_LIVEPATCH': completing patching transition
  163. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  164. livepatch: '$MOD_LIVEPATCH': patching complete
  165. % modprobe $MOD_TARGET
  166. livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
  167. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  168. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  169. $MOD_TARGET: ${MOD_TARGET}_init
  170. % rmmod $MOD_TARGET
  171. $MOD_TARGET: ${MOD_TARGET}_exit
  172. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  173. livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
  174. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  175. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  176. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  177. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  178. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  179. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  180. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  181. livepatch: '$MOD_LIVEPATCH': unpatching complete
  182. % rmmod $MOD_LIVEPATCH"
  183. # A simple test of loading a livepatch without one of its patch target
  184. # klp_objects ever loaded ($MOD_TARGET).
  185. #
  186. # - Load the livepatch.
  187. #
  188. # - As expected, only pre/post-(un)patch handlers are executed for
  189. # vmlinux.
  190. start_test "target module not present"
  191. load_lp $MOD_LIVEPATCH
  192. disable_lp $MOD_LIVEPATCH
  193. unload_lp $MOD_LIVEPATCH
  194. check_result "% modprobe $MOD_LIVEPATCH
  195. livepatch: enabling patch '$MOD_LIVEPATCH'
  196. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  197. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  198. livepatch: '$MOD_LIVEPATCH': starting patching transition
  199. livepatch: '$MOD_LIVEPATCH': completing patching transition
  200. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  201. livepatch: '$MOD_LIVEPATCH': patching complete
  202. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  203. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  204. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  205. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  206. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  207. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  208. livepatch: '$MOD_LIVEPATCH': unpatching complete
  209. % rmmod $MOD_LIVEPATCH"
  210. # Test a scenario where a vmlinux pre-patch callback returns a non-zero
  211. # status (ie, failure).
  212. #
  213. # - First load a target module.
  214. #
  215. # - Load the livepatch module, setting its 'pre_patch_ret' value to -19
  216. # (-ENODEV). When its vmlinux pre-patch callback executes, this
  217. # status code will propagate back to the module-loading subsystem.
  218. # The result is that the insmod command refuses to load the livepatch
  219. # module.
  220. start_test "pre-patch callback -ENODEV"
  221. load_mod $MOD_TARGET
  222. load_failing_mod $MOD_LIVEPATCH pre_patch_ret=-19
  223. unload_mod $MOD_TARGET
  224. check_result "% modprobe $MOD_TARGET
  225. $MOD_TARGET: ${MOD_TARGET}_init
  226. % modprobe $MOD_LIVEPATCH pre_patch_ret=-19
  227. livepatch: enabling patch '$MOD_LIVEPATCH'
  228. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  229. test_klp_callbacks_demo: pre_patch_callback: vmlinux
  230. livepatch: pre-patch callback failed for object 'vmlinux'
  231. livepatch: failed to enable patch '$MOD_LIVEPATCH'
  232. livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
  233. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  234. livepatch: '$MOD_LIVEPATCH': unpatching complete
  235. modprobe: ERROR: could not insert '$MOD_LIVEPATCH': No such device
  236. % rmmod $MOD_TARGET
  237. $MOD_TARGET: ${MOD_TARGET}_exit"
  238. # Similar to the previous test, setup a livepatch such that its vmlinux
  239. # pre-patch callback returns success. However, when a targeted kernel
  240. # module is later loaded, have the livepatch return a failing status
  241. # code.
  242. #
  243. # - Load the livepatch, vmlinux pre-patch callback succeeds.
  244. #
  245. # - Set a trap so subsequent pre-patch callbacks to this livepatch will
  246. # return -ENODEV.
  247. #
  248. # - The livepatch pre-patch callback for subsequently loaded target
  249. # modules will return failure, so the module loader refuses to load
  250. # the kernel module. No post-patch or pre/post-unpatch callbacks are
  251. # executed for this klp_object.
  252. #
  253. # - Pre/post-unpatch callbacks are run for the vmlinux klp_object.
  254. start_test "module_coming + pre-patch callback -ENODEV"
  255. load_lp $MOD_LIVEPATCH
  256. set_pre_patch_ret $MOD_LIVEPATCH -19
  257. load_failing_mod $MOD_TARGET
  258. disable_lp $MOD_LIVEPATCH
  259. unload_lp $MOD_LIVEPATCH
  260. check_result "% modprobe $MOD_LIVEPATCH
  261. livepatch: enabling patch '$MOD_LIVEPATCH'
  262. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  263. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  264. livepatch: '$MOD_LIVEPATCH': starting patching transition
  265. livepatch: '$MOD_LIVEPATCH': completing patching transition
  266. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  267. livepatch: '$MOD_LIVEPATCH': patching complete
  268. % echo -19 > /sys/module/$MOD_LIVEPATCH/parameters/pre_patch_ret
  269. % modprobe $MOD_TARGET
  270. livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
  271. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  272. livepatch: pre-patch callback failed for object '$MOD_TARGET'
  273. livepatch: patch '$MOD_LIVEPATCH' failed for module '$MOD_TARGET', refusing to load module '$MOD_TARGET'
  274. modprobe: ERROR: could not insert '$MOD_TARGET': No such device
  275. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  276. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  277. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  278. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  279. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  280. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  281. livepatch: '$MOD_LIVEPATCH': unpatching complete
  282. % rmmod $MOD_LIVEPATCH"
  283. # Test loading multiple targeted kernel modules. This test-case is
  284. # mainly for comparing with the next test-case.
  285. #
  286. # - Load a target "busy" kernel module which kicks off a worker function
  287. # that immediately exits.
  288. #
  289. # - Proceed with loading the livepatch and another ordinary target
  290. # module. Post-patch callbacks are executed and the transition
  291. # completes quickly.
  292. start_test "multiple target modules"
  293. load_mod $MOD_TARGET_BUSY block_transition=N
  294. load_lp $MOD_LIVEPATCH
  295. load_mod $MOD_TARGET
  296. unload_mod $MOD_TARGET
  297. disable_lp $MOD_LIVEPATCH
  298. unload_lp $MOD_LIVEPATCH
  299. unload_mod $MOD_TARGET_BUSY
  300. check_result "% modprobe $MOD_TARGET_BUSY block_transition=N
  301. $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
  302. $MOD_TARGET_BUSY: busymod_work_func enter
  303. $MOD_TARGET_BUSY: busymod_work_func exit
  304. % modprobe $MOD_LIVEPATCH
  305. livepatch: enabling patch '$MOD_LIVEPATCH'
  306. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  307. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  308. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  309. livepatch: '$MOD_LIVEPATCH': starting patching transition
  310. livepatch: '$MOD_LIVEPATCH': completing patching transition
  311. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  312. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  313. livepatch: '$MOD_LIVEPATCH': patching complete
  314. % modprobe $MOD_TARGET
  315. livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
  316. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  317. $MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  318. $MOD_TARGET: ${MOD_TARGET}_init
  319. % rmmod $MOD_TARGET
  320. $MOD_TARGET: ${MOD_TARGET}_exit
  321. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  322. livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
  323. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  324. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  325. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  326. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  327. $MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  328. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  329. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  330. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  331. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  332. livepatch: '$MOD_LIVEPATCH': unpatching complete
  333. % rmmod $MOD_LIVEPATCH
  334. % rmmod $MOD_TARGET_BUSY
  335. $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
  336. # A similar test as the previous one, but force the "busy" kernel module
  337. # to block the livepatch transition.
  338. #
  339. # The livepatching core will refuse to patch a task that is currently
  340. # executing a to-be-patched function -- the consistency model stalls the
  341. # current patch transition until this safety-check is met. Test a
  342. # scenario where one of a livepatch's target klp_objects sits on such a
  343. # function for a long time. Meanwhile, load and unload other target
  344. # kernel modules while the livepatch transition is in progress.
  345. #
  346. # - Load the "busy" kernel module, this time make its work function loop
  347. #
  348. # - Meanwhile, the livepatch is loaded. Notice that the patch
  349. # transition does not complete as the targeted "busy" module is
  350. # sitting on a to-be-patched function.
  351. #
  352. # - Load a second target module (this one is an ordinary idle kernel
  353. # module). Note that *no* post-patch callbacks will be executed while
  354. # the livepatch is still in transition.
  355. #
  356. # - Request an unload of the simple kernel module. The patch is still
  357. # transitioning, so its pre-unpatch callbacks are skipped.
  358. #
  359. # - Finally the livepatch is disabled. Since none of the patch's
  360. # klp_object's post-patch callbacks executed, the remaining
  361. # klp_object's pre-unpatch callbacks are skipped.
  362. start_test "busy target module"
  363. load_mod $MOD_TARGET_BUSY block_transition=Y
  364. load_lp_nowait $MOD_LIVEPATCH
  365. # Wait until the livepatch reports in-transition state, i.e. that it's
  366. # stalled on $MOD_TARGET_BUSY::busymod_work_func()
  367. loop_until 'grep -q '^1$' /sys/kernel/livepatch/$MOD_LIVEPATCH/transition' ||
  368. die "failed to stall transition"
  369. load_mod $MOD_TARGET
  370. unload_mod $MOD_TARGET
  371. disable_lp $MOD_LIVEPATCH
  372. unload_lp $MOD_LIVEPATCH
  373. unload_mod $MOD_TARGET_BUSY
  374. check_result "% modprobe $MOD_TARGET_BUSY block_transition=Y
  375. $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
  376. $MOD_TARGET_BUSY: busymod_work_func enter
  377. % modprobe $MOD_LIVEPATCH
  378. livepatch: enabling patch '$MOD_LIVEPATCH'
  379. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  380. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  381. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  382. livepatch: '$MOD_LIVEPATCH': starting patching transition
  383. % modprobe $MOD_TARGET
  384. livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
  385. $MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
  386. $MOD_TARGET: ${MOD_TARGET}_init
  387. % rmmod $MOD_TARGET
  388. $MOD_TARGET: ${MOD_TARGET}_exit
  389. livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
  390. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
  391. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  392. livepatch: '$MOD_LIVEPATCH': reversing transition from patching to unpatching
  393. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  394. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  395. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  396. $MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET_BUSY -> [MODULE_STATE_LIVE] Normal state
  397. livepatch: '$MOD_LIVEPATCH': unpatching complete
  398. % rmmod $MOD_LIVEPATCH
  399. % rmmod $MOD_TARGET_BUSY
  400. $MOD_TARGET_BUSY: busymod_work_func exit
  401. $MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
  402. # Test loading multiple livepatches. This test-case is mainly for comparing
  403. # with the next test-case.
  404. #
  405. # - Load and unload two livepatches, pre and post (un)patch callbacks
  406. # execute as each patch progresses through its (un)patching
  407. # transition.
  408. start_test "multiple livepatches"
  409. load_lp $MOD_LIVEPATCH
  410. load_lp $MOD_LIVEPATCH2
  411. disable_lp $MOD_LIVEPATCH2
  412. disable_lp $MOD_LIVEPATCH
  413. unload_lp $MOD_LIVEPATCH2
  414. unload_lp $MOD_LIVEPATCH
  415. check_result "% modprobe $MOD_LIVEPATCH
  416. livepatch: enabling patch '$MOD_LIVEPATCH'
  417. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  418. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  419. livepatch: '$MOD_LIVEPATCH': starting patching transition
  420. livepatch: '$MOD_LIVEPATCH': completing patching transition
  421. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  422. livepatch: '$MOD_LIVEPATCH': patching complete
  423. % modprobe $MOD_LIVEPATCH2
  424. livepatch: enabling patch '$MOD_LIVEPATCH2'
  425. livepatch: '$MOD_LIVEPATCH2': initializing patching transition
  426. $MOD_LIVEPATCH2: pre_patch_callback: vmlinux
  427. livepatch: '$MOD_LIVEPATCH2': starting patching transition
  428. livepatch: '$MOD_LIVEPATCH2': completing patching transition
  429. $MOD_LIVEPATCH2: post_patch_callback: vmlinux
  430. livepatch: '$MOD_LIVEPATCH2': patching complete
  431. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
  432. livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
  433. $MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
  434. livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
  435. livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
  436. $MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
  437. livepatch: '$MOD_LIVEPATCH2': unpatching complete
  438. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
  439. livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
  440. $MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
  441. livepatch: '$MOD_LIVEPATCH': starting unpatching transition
  442. livepatch: '$MOD_LIVEPATCH': completing unpatching transition
  443. $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
  444. livepatch: '$MOD_LIVEPATCH': unpatching complete
  445. % rmmod $MOD_LIVEPATCH2
  446. % rmmod $MOD_LIVEPATCH"
  447. # Load multiple livepatches, but the second as an 'atomic-replace'
  448. # patch. When the latter loads, the original livepatch should be
  449. # disabled and *none* of its pre/post-unpatch callbacks executed. On
  450. # the other hand, when the atomic-replace livepatch is disabled, its
  451. # pre/post-unpatch callbacks *should* be executed.
  452. #
  453. # - Load and unload two livepatches, the second of which has its
  454. # .replace flag set true.
  455. #
  456. # - Pre and post patch callbacks are executed for both livepatches.
  457. #
  458. # - Once the atomic replace module is loaded, only its pre and post
  459. # unpatch callbacks are executed.
  460. start_test "atomic replace"
  461. load_lp $MOD_LIVEPATCH
  462. load_lp $MOD_LIVEPATCH2 replace=1
  463. disable_lp $MOD_LIVEPATCH2
  464. unload_lp $MOD_LIVEPATCH2
  465. unload_lp $MOD_LIVEPATCH
  466. check_result "% modprobe $MOD_LIVEPATCH
  467. livepatch: enabling patch '$MOD_LIVEPATCH'
  468. livepatch: '$MOD_LIVEPATCH': initializing patching transition
  469. $MOD_LIVEPATCH: pre_patch_callback: vmlinux
  470. livepatch: '$MOD_LIVEPATCH': starting patching transition
  471. livepatch: '$MOD_LIVEPATCH': completing patching transition
  472. $MOD_LIVEPATCH: post_patch_callback: vmlinux
  473. livepatch: '$MOD_LIVEPATCH': patching complete
  474. % modprobe $MOD_LIVEPATCH2 replace=1
  475. livepatch: enabling patch '$MOD_LIVEPATCH2'
  476. livepatch: '$MOD_LIVEPATCH2': initializing patching transition
  477. $MOD_LIVEPATCH2: pre_patch_callback: vmlinux
  478. livepatch: '$MOD_LIVEPATCH2': starting patching transition
  479. livepatch: '$MOD_LIVEPATCH2': completing patching transition
  480. $MOD_LIVEPATCH2: post_patch_callback: vmlinux
  481. livepatch: '$MOD_LIVEPATCH2': patching complete
  482. % echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH2/enabled
  483. livepatch: '$MOD_LIVEPATCH2': initializing unpatching transition
  484. $MOD_LIVEPATCH2: pre_unpatch_callback: vmlinux
  485. livepatch: '$MOD_LIVEPATCH2': starting unpatching transition
  486. livepatch: '$MOD_LIVEPATCH2': completing unpatching transition
  487. $MOD_LIVEPATCH2: post_unpatch_callback: vmlinux
  488. livepatch: '$MOD_LIVEPATCH2': unpatching complete
  489. % rmmod $MOD_LIVEPATCH2
  490. % rmmod $MOD_LIVEPATCH"
  491. exit 0