Skip to content

Commit d3d9443

Browse files
committed
Merge tag 'livepatching-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching
Pull livepatching updates from Petr Mladek: - Add two new selftests * tag 'livepatching-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: selftests/livepatch: add test for module function patching selftests: livepatch: test-ftrace: livepatch a traced function
2 parents 090748e + 448c0f8 commit d3d9443

5 files changed

Lines changed: 230 additions & 0 deletions

File tree

tools/testing/selftests/livepatch/test-ftrace.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,40 @@ livepatch: '$MOD_LIVEPATCH': completing unpatching transition
9595
livepatch: '$MOD_LIVEPATCH': unpatching complete
9696
% rmmod $MOD_LIVEPATCH"
9797

98+
99+
# - trace a function
100+
# - verify livepatch can load targgeting on the same traced function
101+
# - check if the livepatch is in effect
102+
# - reset trace and unload livepatch
103+
104+
start_test "livepatch a traced function and check that the live patch remains in effect"
105+
106+
FUNCTION_NAME="cmdline_proc_show"
107+
108+
trace_function "$FUNCTION_NAME"
109+
load_lp $MOD_LIVEPATCH
110+
111+
if [[ "$(cat /proc/cmdline)" == "$MOD_LIVEPATCH: this has been live patched" ]] ; then
112+
log "livepatch: ok"
113+
fi
114+
115+
check_traced_functions "$FUNCTION_NAME"
116+
117+
disable_lp $MOD_LIVEPATCH
118+
unload_lp $MOD_LIVEPATCH
119+
120+
check_result "% insmod test_modules/$MOD_LIVEPATCH.ko
121+
livepatch: enabling patch '$MOD_LIVEPATCH'
122+
livepatch: '$MOD_LIVEPATCH': initializing patching transition
123+
livepatch: '$MOD_LIVEPATCH': starting patching transition
124+
livepatch: '$MOD_LIVEPATCH': completing patching transition
125+
livepatch: '$MOD_LIVEPATCH': patching complete
126+
livepatch: ok
127+
% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
128+
livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
129+
livepatch: '$MOD_LIVEPATCH': starting unpatching transition
130+
livepatch: '$MOD_LIVEPATCH': completing unpatching transition
131+
livepatch: '$MOD_LIVEPATCH': unpatching complete
132+
% rmmod $MOD_LIVEPATCH"
133+
98134
exit 0

tools/testing/selftests/livepatch/test-livepatch.sh

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ MOD_LIVEPATCH1=test_klp_livepatch
88
MOD_LIVEPATCH2=test_klp_syscall
99
MOD_LIVEPATCH3=test_klp_callbacks_demo
1010
MOD_REPLACE=test_klp_atomic_replace
11+
MOD_TARGET=test_klp_mod_target
12+
MOD_TARGET_PATCH=test_klp_mod_patch
1113

1214
setup_config
1315

@@ -196,4 +198,102 @@ livepatch: '$MOD_REPLACE': unpatching complete
196198
% rmmod $MOD_REPLACE"
197199

198200

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+
209+
start_test "module function patching"
210+
211+
load_mod $MOD_TARGET
212+
213+
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
214+
echo -e "FAIL\n\n"
215+
die "livepatch kselftest(s) failed"
216+
fi
217+
218+
load_lp $MOD_TARGET_PATCH
219+
220+
if [[ "$(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"
223+
fi
224+
225+
disable_lp $MOD_TARGET_PATCH
226+
unload_lp $MOD_TARGET_PATCH
227+
228+
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
229+
echo -e "FAIL\n\n"
230+
die "livepatch kselftest(s) failed"
231+
fi
232+
233+
unload_mod $MOD_TARGET
234+
235+
check_result "% insmod test_modules/$MOD_TARGET.ko
236+
$MOD_TARGET: test_klp_mod_target_init
237+
% insmod test_modules/$MOD_TARGET_PATCH.ko
238+
livepatch: enabling patch '$MOD_TARGET_PATCH'
239+
livepatch: '$MOD_TARGET_PATCH': initializing patching transition
240+
livepatch: '$MOD_TARGET_PATCH': starting patching transition
241+
livepatch: '$MOD_TARGET_PATCH': completing patching transition
242+
livepatch: '$MOD_TARGET_PATCH': patching complete
243+
% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
244+
livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
245+
livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
246+
livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
247+
livepatch: '$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+
260+
start_test "module function patching (livepatch first)"
261+
262+
load_lp $MOD_TARGET_PATCH
263+
load_mod $MOD_TARGET
264+
265+
if [[ "$(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"
268+
fi
269+
270+
disable_lp $MOD_TARGET_PATCH
271+
unload_lp $MOD_TARGET_PATCH
272+
273+
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
274+
echo -e "FAIL\n\n"
275+
die "livepatch kselftest(s) failed"
276+
fi
277+
278+
unload_mod $MOD_TARGET
279+
280+
check_result "% insmod test_modules/$MOD_TARGET_PATCH.ko
281+
livepatch: enabling patch '$MOD_TARGET_PATCH'
282+
livepatch: '$MOD_TARGET_PATCH': initializing patching transition
283+
livepatch: '$MOD_TARGET_PATCH': starting patching transition
284+
livepatch: '$MOD_TARGET_PATCH': completing patching transition
285+
livepatch: '$MOD_TARGET_PATCH': patching complete
286+
% insmod test_modules/$MOD_TARGET.ko
287+
livepatch: 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
290+
livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
291+
livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
292+
livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
293+
livepatch: '$MOD_TARGET_PATCH': unpatching complete
294+
% rmmod $MOD_TARGET_PATCH
295+
% rmmod $MOD_TARGET
296+
$MOD_TARGET: test_klp_mod_target_exit"
297+
298+
199299
exit 0

tools/testing/selftests/livepatch/test_modules/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ obj-m += test_klp_atomic_replace.o \
88
test_klp_callbacks_mod.o \
99
test_klp_kprobe.o \
1010
test_klp_livepatch.o \
11+
test_klp_mod_patch.o \
12+
test_klp_mod_target.o \
1113
test_klp_shadow_vars.o \
1214
test_klp_state.o \
1315
test_klp_state2.o \
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (C) 2026 Pablo Hugen <phugen@redhat.com>
3+
4+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5+
6+
#include <linux/module.h>
7+
#include <linux/kernel.h>
8+
#include <linux/livepatch.h>
9+
#include <linux/seq_file.h>
10+
11+
static int livepatch_mod_target_show(struct seq_file *m, void *v)
12+
{
13+
seq_printf(m, "%s: %s\n", THIS_MODULE->name,
14+
"this has been live patched");
15+
return 0;
16+
}
17+
18+
static struct klp_func funcs[] = {
19+
{
20+
.old_name = "test_klp_mod_target_show",
21+
.new_func = livepatch_mod_target_show,
22+
},
23+
{},
24+
};
25+
26+
static struct klp_object objs[] = {
27+
{
28+
.name = "test_klp_mod_target",
29+
.funcs = funcs,
30+
},
31+
{},
32+
};
33+
34+
static struct klp_patch patch = {
35+
.mod = THIS_MODULE,
36+
.objs = objs,
37+
};
38+
39+
static int test_klp_mod_patch_init(void)
40+
{
41+
return klp_enable_patch(&patch);
42+
}
43+
44+
static void test_klp_mod_patch_exit(void)
45+
{
46+
}
47+
48+
module_init(test_klp_mod_patch_init);
49+
module_exit(test_klp_mod_patch_exit);
50+
MODULE_LICENSE("GPL");
51+
MODULE_INFO(livepatch, "Y");
52+
MODULE_AUTHOR("Pablo Hugen <phugen@redhat.com>");
53+
MODULE_DESCRIPTION("Livepatch test: patch for module-provided function");
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (C) 2026 Pablo Hugen <phugen@redhat.com>
3+
4+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5+
6+
#include <linux/module.h>
7+
#include <linux/kernel.h>
8+
#include <linux/proc_fs.h>
9+
#include <linux/seq_file.h>
10+
11+
static struct proc_dir_entry *pde;
12+
13+
static noinline int test_klp_mod_target_show(struct seq_file *m, void *v)
14+
{
15+
seq_printf(m, "%s: %s\n", THIS_MODULE->name, "original output");
16+
return 0;
17+
}
18+
19+
static int test_klp_mod_target_init(void)
20+
{
21+
pr_info("%s\n", __func__);
22+
pde = proc_create_single("test_klp_mod_target", 0, NULL,
23+
test_klp_mod_target_show);
24+
if (!pde)
25+
return -ENOMEM;
26+
return 0;
27+
}
28+
29+
static void test_klp_mod_target_exit(void)
30+
{
31+
pr_info("%s\n", __func__);
32+
proc_remove(pde);
33+
}
34+
35+
module_init(test_klp_mod_target_init);
36+
module_exit(test_klp_mod_target_exit);
37+
MODULE_LICENSE("GPL");
38+
MODULE_AUTHOR("Pablo Hugen <phugen@redhat.com>");
39+
MODULE_DESCRIPTION("Livepatch test: target module with proc entry");

0 commit comments

Comments
 (0)