xref: /linux/tools/testing/selftests/livepatch/test-livepatch.sh (revision e2683c8868d03382da7e1ce8453b543a043066d1)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
4
5. $(dirname $0)/functions.sh
6
7MOD_LIVEPATCH1=test_klp_livepatch
8MOD_LIVEPATCH2=test_klp_syscall
9MOD_LIVEPATCH3=test_klp_callbacks_demo
10MOD_REPLACE=test_klp_atomic_replace
11MOD_TARGET=test_klp_mod_target
12MOD_TARGET_PATCH=test_klp_mod_patch
13
14setup_config
15
16
17# - load a livepatch that modifies the output from /proc/cmdline and
18#   verify correct behavior
19# - unload the livepatch and make sure the patch was removed
20
21start_test "basic function patching"
22
23load_lp $MOD_LIVEPATCH1
24
25if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH1: this has been live patched" ]] ; then
26	echo -e "FAIL\n\n"
27	die "livepatch kselftest(s) failed"
28fi
29
30disable_lp $MOD_LIVEPATCH1
31unload_lp $MOD_LIVEPATCH1
32
33if [[ "$(cat /proc/cmdline)" == "$MOD_LIVEPATCH1: this has been live patched" ]] ; then
34	echo -e "FAIL\n\n"
35	die "livepatch kselftest(s) failed"
36fi
37
38check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko
39livepatch: enabling patch '$MOD_LIVEPATCH1'
40livepatch: '$MOD_LIVEPATCH1': initializing patching transition
41livepatch: '$MOD_LIVEPATCH1': starting patching transition
42livepatch: '$MOD_LIVEPATCH1': completing patching transition
43livepatch: '$MOD_LIVEPATCH1': patching complete
44% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH1/enabled
45livepatch: '$MOD_LIVEPATCH1': initializing unpatching transition
46livepatch: '$MOD_LIVEPATCH1': starting unpatching transition
47livepatch: '$MOD_LIVEPATCH1': completing unpatching transition
48livepatch: '$MOD_LIVEPATCH1': unpatching complete
49% rmmod $MOD_LIVEPATCH1"
50
51
52# - load a livepatch that modifies the output from /proc/cmdline and
53#   verify correct behavior
54# - load another livepatch and verify that both livepatches are active
55# - unload the second livepatch and verify that the first is still active
56# - unload the first livepatch and verify none are active
57
58start_test "multiple livepatches"
59
60load_lp $MOD_LIVEPATCH1
61
62grep 'live patched' /proc/cmdline > /dev/kmsg
63grep 'live patched' /proc/meminfo > /dev/kmsg
64
65load_lp $MOD_REPLACE replace=0
66
67grep 'live patched' /proc/cmdline > /dev/kmsg
68grep 'live patched' /proc/meminfo > /dev/kmsg
69
70disable_lp $MOD_REPLACE
71unload_lp $MOD_REPLACE
72
73grep 'live patched' /proc/cmdline > /dev/kmsg
74grep 'live patched' /proc/meminfo > /dev/kmsg
75
76disable_lp $MOD_LIVEPATCH1
77unload_lp $MOD_LIVEPATCH1
78
79grep 'live patched' /proc/cmdline > /dev/kmsg
80grep 'live patched' /proc/meminfo > /dev/kmsg
81
82check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko
83livepatch: enabling patch '$MOD_LIVEPATCH1'
84livepatch: '$MOD_LIVEPATCH1': initializing patching transition
85livepatch: '$MOD_LIVEPATCH1': starting patching transition
86livepatch: '$MOD_LIVEPATCH1': completing patching transition
87livepatch: '$MOD_LIVEPATCH1': patching complete
88$MOD_LIVEPATCH1: this has been live patched
89% insmod test_modules/$MOD_REPLACE.ko replace=0
90livepatch: enabling patch '$MOD_REPLACE'
91livepatch: '$MOD_REPLACE': initializing patching transition
92livepatch: '$MOD_REPLACE': starting patching transition
93livepatch: '$MOD_REPLACE': completing patching transition
94livepatch: '$MOD_REPLACE': patching complete
95$MOD_LIVEPATCH1: this has been live patched
96$MOD_REPLACE: this has been live patched
97% echo 0 > $SYSFS_KLP_DIR/$MOD_REPLACE/enabled
98livepatch: '$MOD_REPLACE': initializing unpatching transition
99livepatch: '$MOD_REPLACE': starting unpatching transition
100livepatch: '$MOD_REPLACE': completing unpatching transition
101livepatch: '$MOD_REPLACE': unpatching complete
102% rmmod $MOD_REPLACE
103$MOD_LIVEPATCH1: this has been live patched
104% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH1/enabled
105livepatch: '$MOD_LIVEPATCH1': initializing unpatching transition
106livepatch: '$MOD_LIVEPATCH1': starting unpatching transition
107livepatch: '$MOD_LIVEPATCH1': completing unpatching transition
108livepatch: '$MOD_LIVEPATCH1': unpatching complete
109% rmmod $MOD_LIVEPATCH1"
110
111
112# - load a livepatch that modifies the output from /proc/cmdline and
113#   verify correct behavior
114# - load two additional livepatches and check the number of livepatch modules
115#   applied
116# - load an atomic replace livepatch and check that the other three modules were
117#   disabled
118# - remove all livepatches besides the atomic replace one and verify that the
119#   atomic replace livepatch is still active
120# - remove the atomic replace livepatch and verify that none are active
121
122start_test "atomic replace livepatch"
123
124load_lp $MOD_LIVEPATCH1
125
126grep 'live patched' /proc/cmdline > /dev/kmsg
127grep 'live patched' /proc/meminfo > /dev/kmsg
128
129for mod in $MOD_LIVEPATCH2 $MOD_LIVEPATCH3; do
130	load_lp "$mod"
131done
132
133mods=($SYSFS_KLP_DIR/*)
134nmods=${#mods[@]}
135if [ "$nmods" -ne 3 ]; then
136	die "Expecting three modules listed, found $nmods"
137fi
138
139load_lp $MOD_REPLACE replace=1
140
141grep 'live patched' /proc/cmdline > /dev/kmsg
142grep 'live patched' /proc/meminfo > /dev/kmsg
143
144loop_until 'mods=($SYSFS_KLP_DIR/*); nmods=${#mods[@]}; [[ "$nmods" -eq 1 ]]' ||
145        die "Expecting only one moduled listed, found $nmods"
146
147# These modules were disabled by the atomic replace
148for mod in $MOD_LIVEPATCH3 $MOD_LIVEPATCH2 $MOD_LIVEPATCH1; do
149	unload_lp "$mod"
150done
151
152grep 'live patched' /proc/cmdline > /dev/kmsg
153grep 'live patched' /proc/meminfo > /dev/kmsg
154
155disable_lp $MOD_REPLACE
156unload_lp $MOD_REPLACE
157
158grep 'live patched' /proc/cmdline > /dev/kmsg
159grep 'live patched' /proc/meminfo > /dev/kmsg
160
161check_result "% insmod test_modules/$MOD_LIVEPATCH1.ko
162livepatch: enabling patch '$MOD_LIVEPATCH1'
163livepatch: '$MOD_LIVEPATCH1': initializing patching transition
164livepatch: '$MOD_LIVEPATCH1': starting patching transition
165livepatch: '$MOD_LIVEPATCH1': completing patching transition
166livepatch: '$MOD_LIVEPATCH1': patching complete
167$MOD_LIVEPATCH1: this has been live patched
168% insmod test_modules/$MOD_LIVEPATCH2.ko
169livepatch: enabling patch '$MOD_LIVEPATCH2'
170livepatch: '$MOD_LIVEPATCH2': initializing patching transition
171livepatch: '$MOD_LIVEPATCH2': starting patching transition
172livepatch: '$MOD_LIVEPATCH2': completing patching transition
173livepatch: '$MOD_LIVEPATCH2': patching complete
174% insmod test_modules/$MOD_LIVEPATCH3.ko
175livepatch: enabling patch '$MOD_LIVEPATCH3'
176livepatch: '$MOD_LIVEPATCH3': initializing patching transition
177$MOD_LIVEPATCH3: pre_patch_callback: vmlinux
178livepatch: '$MOD_LIVEPATCH3': starting patching transition
179livepatch: '$MOD_LIVEPATCH3': completing patching transition
180$MOD_LIVEPATCH3: post_patch_callback: vmlinux
181livepatch: '$MOD_LIVEPATCH3': patching complete
182% insmod test_modules/$MOD_REPLACE.ko replace=1
183livepatch: enabling patch '$MOD_REPLACE'
184livepatch: '$MOD_REPLACE': initializing patching transition
185livepatch: '$MOD_REPLACE': starting patching transition
186livepatch: '$MOD_REPLACE': completing patching transition
187livepatch: '$MOD_REPLACE': patching complete
188$MOD_REPLACE: this has been live patched
189% rmmod $MOD_LIVEPATCH3
190% rmmod $MOD_LIVEPATCH2
191% rmmod $MOD_LIVEPATCH1
192$MOD_REPLACE: this has been live patched
193% echo 0 > $SYSFS_KLP_DIR/$MOD_REPLACE/enabled
194livepatch: '$MOD_REPLACE': initializing unpatching transition
195livepatch: '$MOD_REPLACE': starting unpatching transition
196livepatch: '$MOD_REPLACE': completing unpatching transition
197livepatch: '$MOD_REPLACE': unpatching complete
198% rmmod $MOD_REPLACE"
199
200
201# - load a target module that provides /proc/test_klp_mod_target with
202#   original output
203# - load a livepatch that patches the target module's show function
204# - verify the proc entry returns livepatched output
205# - disable and unload the livepatch
206# - verify the proc entry returns original output again
207# - unload the target module
208
209start_test "module function patching"
210
211load_mod $MOD_TARGET
212
213if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
214	echo -e "FAIL\n\n"
215	die "livepatch kselftest(s) failed"
216fi
217
218load_lp $MOD_TARGET_PATCH
219
220if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET_PATCH: this has been live patched" ]] ; then
221	echo -e "FAIL\n\n"
222	die "livepatch kselftest(s) failed"
223fi
224
225disable_lp $MOD_TARGET_PATCH
226unload_lp $MOD_TARGET_PATCH
227
228if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
229	echo -e "FAIL\n\n"
230	die "livepatch kselftest(s) failed"
231fi
232
233unload_mod $MOD_TARGET
234
235check_result "% insmod test_modules/$MOD_TARGET.ko
236$MOD_TARGET: test_klp_mod_target_init
237% insmod test_modules/$MOD_TARGET_PATCH.ko
238livepatch: enabling patch '$MOD_TARGET_PATCH'
239livepatch: '$MOD_TARGET_PATCH': initializing patching transition
240livepatch: '$MOD_TARGET_PATCH': starting patching transition
241livepatch: '$MOD_TARGET_PATCH': completing patching transition
242livepatch: '$MOD_TARGET_PATCH': patching complete
243% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
244livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
245livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
246livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
247livepatch: '$MOD_TARGET_PATCH': unpatching complete
248% rmmod $MOD_TARGET_PATCH
249% rmmod $MOD_TARGET
250$MOD_TARGET: test_klp_mod_target_exit"
251
252
253# - load a livepatch that targets a not-yet-loaded module
254# - load the target module: klp_module_coming patches it immediately
255# - verify the proc entry returns livepatched output
256# - disable and unload the livepatch
257# - verify the proc entry returns original output again
258# - unload the target module
259
260start_test "module function patching (livepatch first)"
261
262load_lp $MOD_TARGET_PATCH
263load_mod $MOD_TARGET
264
265if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET_PATCH: this has been live patched" ]] ; then
266	echo -e "FAIL\n\n"
267	die "livepatch kselftest(s) failed"
268fi
269
270disable_lp $MOD_TARGET_PATCH
271unload_lp $MOD_TARGET_PATCH
272
273if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
274	echo -e "FAIL\n\n"
275	die "livepatch kselftest(s) failed"
276fi
277
278unload_mod $MOD_TARGET
279
280check_result "% insmod test_modules/$MOD_TARGET_PATCH.ko
281livepatch: enabling patch '$MOD_TARGET_PATCH'
282livepatch: '$MOD_TARGET_PATCH': initializing patching transition
283livepatch: '$MOD_TARGET_PATCH': starting patching transition
284livepatch: '$MOD_TARGET_PATCH': completing patching transition
285livepatch: '$MOD_TARGET_PATCH': patching complete
286% insmod test_modules/$MOD_TARGET.ko
287livepatch: applying patch '$MOD_TARGET_PATCH' to loading module '$MOD_TARGET'
288$MOD_TARGET: test_klp_mod_target_init
289% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
290livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
291livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
292livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
293livepatch: '$MOD_TARGET_PATCH': unpatching complete
294% rmmod $MOD_TARGET_PATCH
295% rmmod $MOD_TARGET
296$MOD_TARGET: test_klp_mod_target_exit"
297
298
299exit 0
300