Skip to content

Commit 62597ed

Browse files
jubalhpmladek
authored andcommitted
selftests: livepatch: test livepatching a kprobed function
The test proves that a function that is being kprobed and uses a post_handler cannot be livepatched. Only one ftrace_ops with FTRACE_OPS_FL_IPMODIFY set may be registered to any given function at a time. Note that the conflicting kprobe could not be created using the tracefs interface, see Documentation/trace/kprobetrace.rst. This interface uses only the pre_handler(), see alloc_trace_kprobe(). But FTRACE_OPS_FL_IPMODIFY is used only when the kprobe is using a post_handler, see arm_kprobe_ftrace(). Signed-off-by: Michael Vetter <mvetter@suse.com> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Reviewed-by: Joe Lawrence <joe.lawrence@redhat.com> Tested-by: Marcos Paulo de Souza <mpdesouza@suse.com> Reviewed-by: Marcos Paulo de Souza <mpdesouza@suse.com> Reviewed-by: Petr Mladek <pmladek@suse.com> Tested-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20241017200132.21946-4-mvetter@suse.com Signed-off-by: Petr Mladek <pmladek@suse.com>
1 parent 5976628 commit 62597ed

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

tools/testing/selftests/livepatch/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ TEST_PROGS := \
1010
test-state.sh \
1111
test-ftrace.sh \
1212
test-sysfs.sh \
13-
test-syscall.sh
13+
test-syscall.sh \
14+
test-kprobe.sh
1415

1516
TEST_FILES := settings
1617

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
# Copyright (C) 2024 SUSE
4+
# Author: Michael Vetter <mvetter@suse.com>
5+
6+
. $(dirname $0)/functions.sh
7+
8+
MOD_LIVEPATCH=test_klp_livepatch
9+
MOD_KPROBE=test_klp_kprobe
10+
11+
setup_config
12+
13+
# Kprobe a function and verify that we can't livepatch that same function
14+
# when it uses a post_handler since only one IPMODIFY maybe be registered
15+
# to any given function at a time.
16+
17+
start_test "livepatch interaction with kprobed function with post_handler"
18+
19+
echo 1 > "$SYSFS_KPROBES_DIR/enabled"
20+
21+
load_mod $MOD_KPROBE has_post_handler=true
22+
load_failing_mod $MOD_LIVEPATCH
23+
unload_mod $MOD_KPROBE
24+
25+
check_result "% insmod test_modules/test_klp_kprobe.ko has_post_handler=true
26+
% insmod test_modules/$MOD_LIVEPATCH.ko
27+
livepatch: enabling patch '$MOD_LIVEPATCH'
28+
livepatch: '$MOD_LIVEPATCH': initializing patching transition
29+
livepatch: failed to register ftrace handler for function 'cmdline_proc_show' (-16)
30+
livepatch: failed to patch object 'vmlinux'
31+
livepatch: failed to enable patch '$MOD_LIVEPATCH'
32+
livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
33+
livepatch: '$MOD_LIVEPATCH': completing unpatching transition
34+
livepatch: '$MOD_LIVEPATCH': unpatching complete
35+
insmod: ERROR: could not insert module test_modules/$MOD_LIVEPATCH.ko: Device or resource busy
36+
% rmmod test_klp_kprobe"
37+
38+
start_test "livepatch interaction with kprobed function without post_handler"
39+
40+
load_mod $MOD_KPROBE has_post_handler=false
41+
load_lp $MOD_LIVEPATCH
42+
43+
unload_mod $MOD_KPROBE
44+
disable_lp $MOD_LIVEPATCH
45+
unload_lp $MOD_LIVEPATCH
46+
47+
check_result "% insmod test_modules/test_klp_kprobe.ko has_post_handler=false
48+
% insmod test_modules/$MOD_LIVEPATCH.ko
49+
livepatch: enabling patch '$MOD_LIVEPATCH'
50+
livepatch: '$MOD_LIVEPATCH': initializing patching transition
51+
livepatch: '$MOD_LIVEPATCH': starting patching transition
52+
livepatch: '$MOD_LIVEPATCH': completing patching transition
53+
livepatch: '$MOD_LIVEPATCH': patching complete
54+
% rmmod test_klp_kprobe
55+
% echo 0 > /sys/kernel/livepatch/$MOD_LIVEPATCH/enabled
56+
livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
57+
livepatch: '$MOD_LIVEPATCH': starting unpatching transition
58+
livepatch: '$MOD_LIVEPATCH': completing unpatching transition
59+
livepatch: '$MOD_LIVEPATCH': unpatching complete
60+
% rmmod $MOD_LIVEPATCH"
61+
62+
exit 0

tools/testing/selftests/livepatch/test_modules/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ obj-m += test_klp_atomic_replace.o \
66
test_klp_callbacks_demo.o \
77
test_klp_callbacks_demo2.o \
88
test_klp_callbacks_mod.o \
9+
test_klp_kprobe.o \
910
test_klp_livepatch.o \
11+
test_klp_shadow_vars.o \
1012
test_klp_state.o \
1113
test_klp_state2.o \
1214
test_klp_state3.o \
13-
test_klp_shadow_vars.o \
1415
test_klp_syscall.o
1516

1617
# Ensure that KDIR exists, otherwise skip the compilation
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (C) 2024 Marcos Paulo de Souza <mpdesouza@suse.com>
3+
// Copyright (C) 2024 Michael Vetter <mvetter@suse.com>
4+
5+
#include <linux/kernel.h>
6+
#include <linux/module.h>
7+
#include <linux/kprobes.h>
8+
9+
static bool has_post_handler = true;
10+
module_param(has_post_handler, bool, 0444);
11+
12+
static void __kprobes post_handler(struct kprobe *p, struct pt_regs *regs,
13+
unsigned long flags)
14+
{
15+
}
16+
17+
static struct kprobe kp = {
18+
.symbol_name = "cmdline_proc_show",
19+
};
20+
21+
static int __init kprobe_init(void)
22+
{
23+
if (has_post_handler)
24+
kp.post_handler = post_handler;
25+
26+
return register_kprobe(&kp);
27+
}
28+
29+
static void __exit kprobe_exit(void)
30+
{
31+
unregister_kprobe(&kp);
32+
}
33+
34+
module_init(kprobe_init)
35+
module_exit(kprobe_exit)
36+
MODULE_LICENSE("GPL");
37+
MODULE_AUTHOR("Michael Vetter <mvetter@suse.com>");
38+
MODULE_DESCRIPTION("Livepatch test: kprobe function");

0 commit comments

Comments
 (0)