From 376c879e04fc7abec617bc6897479acd0b605f8c Mon Sep 17 00:00:00 2001 From: Yafang Shao Date: Thu, 27 Feb 2025 10:47:32 +0800 Subject: [PATCH 1/5] livepatch: Add comment to clarify klp_add_nops() Add detailed comments to clarify the purpose of klp_add_nops() function. These comments are based on Petr's explanation[0]. Link: https://lore.kernel.org/all/Z6XUA7D0eU_YDMVp@pathway.suse.cz/ [0] Suggested-by: Petr Mladek Suggested-by: Josh Poimboeuf Signed-off-by: Yafang Shao Reviewed-by: Petr Mladek Link: https://lore.kernel.org/r/20250227024733.16989-2-laoar.shao@gmail.com Signed-off-by: Petr Mladek --- kernel/livepatch/core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 0cd39954d5a10..4a0fb7978d0df 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -601,9 +601,12 @@ static int klp_add_object_nops(struct klp_patch *patch, } /* - * Add 'nop' functions which simply return to the caller to run - * the original function. The 'nop' functions are added to a - * patch to facilitate a 'replace' mode. + * Add 'nop' functions which simply return to the caller to run the + * original function. + * + * They are added only when the atomic replace mode is used and only for + * functions which are currently livepatched but are no longer included + * in the new livepatch. */ static int klp_add_nops(struct klp_patch *patch) { From 4deb3b259fd39e134717878727eaacf5713dd208 Mon Sep 17 00:00:00 2001 From: Vincenzo MEZZELA Date: Thu, 27 Feb 2025 17:39:29 +0100 Subject: [PATCH 2/5] docs: livepatch: move text out of code block Part of the documentation text is included in the readelf output code block. Hence, split the code block and move the affected text outside. Signed-off-by: Vincenzo MEZZELA Acked-by: Miroslav Benes Reviewed-by: Bagas Sanjaya Link: https://lore.kernel.org/r/20250227163929.141053-1-vincenzo.mezzela@suse.com Signed-off-by: Petr Mladek --- Documentation/livepatch/module-elf-format.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/livepatch/module-elf-format.rst b/Documentation/livepatch/module-elf-format.rst index a03ed02ec57e2..5d48778d4dfc2 100644 --- a/Documentation/livepatch/module-elf-format.rst +++ b/Documentation/livepatch/module-elf-format.rst @@ -217,16 +217,19 @@ livepatch relocation section refer to their respective symbols with their symbol indices, and the original symbol indices (and thus the symtab ordering) must be preserved in order for apply_relocate_add() to find the right symbol. -For example, take this particular rela from a livepatch module::: +For example, take this particular rela from a livepatch module:: Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries: Offset Info Type Symbol's Value Symbol's Name + Addend 000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4 - This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol index is encoded - in 'Info'. Here its symbol index is 0x5e, which is 94 in decimal, which refers to the - symbol index 94. - And in this patch module's corresponding symbol table, symbol index 94 refers to that very symbol: +This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol +index is encoded in 'Info'. Here its symbol index is 0x5e, which is 94 in +decimal, which refers to the symbol index 94. + +And in this patch module's corresponding symbol table, symbol index 94 refers +to that very symbol:: + [ snip ] 94: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.printk,0 [ snip ] From 59481b8bd0f038ca99f041566c1c04d069b54dc7 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Tue, 18 Mar 2025 11:15:18 -0700 Subject: [PATCH 3/5] selftest/livepatch: Only run test-kprobe with CONFIG_KPROBES_ON_FTRACE CONFIG_KPROBES_ON_FTRACE is required for test-kprobe. Skip test-kprobe when CONFIG_KPROBES_ON_FTRACE is not set. Since some kernel may not have /proc/config.gz, grep for kprobe_ftrace_ops from /proc/kallsyms to check whether CONFIG_KPROBES_ON_FTRACE is enabled. Signed-off-by: Song Liu Acked-by: Joe Lawrence Acked-by: Miroslav Benes Link: https://lore.kernel.org/r/20250318181518.1055532-1-song@kernel.org [pmladek@suse.com: Call grep with -q option.] Reviewed-by: Petr Mladek Tested-by: Petr Mladek Signed-off-by: Petr Mladek --- tools/testing/selftests/livepatch/test-kprobe.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/livepatch/test-kprobe.sh b/tools/testing/selftests/livepatch/test-kprobe.sh index 115065156016a..b67dfad03d97f 100755 --- a/tools/testing/selftests/livepatch/test-kprobe.sh +++ b/tools/testing/selftests/livepatch/test-kprobe.sh @@ -5,6 +5,8 @@ . $(dirname $0)/functions.sh +grep -q kprobe_ftrace_ops /proc/kallsyms || skip "test-kprobe requires CONFIG_KPROBES_ON_FTRACE" + MOD_LIVEPATCH=test_klp_livepatch MOD_KPROBE=test_klp_kprobe From 2ca7cd80207e458b06c11c2b0de8d975a48f51cc Mon Sep 17 00:00:00 2001 From: Filipe Xavier Date: Mon, 24 Mar 2025 19:50:18 -0300 Subject: [PATCH 4/5] selftests: livepatch: add new ftrace helpers functions Add new ftrace helpers functions cleanup_tracing, trace_function and check_traced_functions. Signed-off-by: Filipe Xavier Acked-by: Miroslav Benes Acked-by: Joe Lawrence Reviewed-by: Petr Mladek Tested-by: Petr Mladek Link: https://lore.kernel.org/r/20250324-ftrace-sftest-livepatch-v3-1-d9d7cc386c75@gmail.com Signed-off-by: Petr Mladek --- .../testing/selftests/livepatch/functions.sh | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh index e5d06fb402335..f5d1915bc95b6 100644 --- a/tools/testing/selftests/livepatch/functions.sh +++ b/tools/testing/selftests/livepatch/functions.sh @@ -10,6 +10,7 @@ SYSFS_KERNEL_DIR="/sys/kernel" SYSFS_KLP_DIR="$SYSFS_KERNEL_DIR/livepatch" SYSFS_DEBUG_DIR="$SYSFS_KERNEL_DIR/debug" SYSFS_KPROBES_DIR="$SYSFS_DEBUG_DIR/kprobes" +SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing" # Kselftest framework requirement - SKIP code is 4 ksft_skip=4 @@ -62,6 +63,9 @@ function push_config() { awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled) KPROBE_ENABLED=$(cat "$SYSFS_KPROBES_DIR/enabled") + TRACING_ON=$(cat "$SYSFS_TRACING_DIR/tracing_on") + CURRENT_TRACER=$(cat "$SYSFS_TRACING_DIR/current_tracer") + FTRACE_FILTER=$(cat "$SYSFS_TRACING_DIR/set_ftrace_filter") } function pop_config() { @@ -74,6 +78,17 @@ function pop_config() { if [[ -n "$KPROBE_ENABLED" ]]; then echo "$KPROBE_ENABLED" > "$SYSFS_KPROBES_DIR/enabled" fi + if [[ -n "$TRACING_ON" ]]; then + echo "$TRACING_ON" > "$SYSFS_TRACING_DIR/tracing_on" + fi + if [[ -n "$CURRENT_TRACER" ]]; then + echo "$CURRENT_TRACER" > "$SYSFS_TRACING_DIR/current_tracer" + fi + if [[ -n "$FTRACE_FILTER" ]]; then + echo "$FTRACE_FILTER" \ + | sed -e "/#### all functions enabled ####/d" \ + > "$SYSFS_TRACING_DIR/set_ftrace_filter" + fi } function set_dynamic_debug() { @@ -351,3 +366,37 @@ function check_sysfs_value() { die "Unexpected value in $path: $expected_value vs. $value" fi } + +# cleanup_tracing() - stop and clean up function tracing +function cleanup_tracing() { + echo 0 > "$SYSFS_TRACING_DIR/tracing_on" + echo "" > "$SYSFS_TRACING_DIR/set_ftrace_filter" + echo "nop" > "$SYSFS_TRACING_DIR/current_tracer" + echo "" > "$SYSFS_TRACING_DIR/trace" +} + +# trace_function(function) - start tracing of a function +# function - to be traced function +function trace_function() { + local function="$1"; shift + + cleanup_tracing + + echo "function" > "$SYSFS_TRACING_DIR/current_tracer" + echo "$function" > "$SYSFS_TRACING_DIR/set_ftrace_filter" + echo 1 > "$SYSFS_TRACING_DIR/tracing_on" +} + +# check_traced_functions(functions...) - check whether each function appeared in the trace log +# functions - list of functions to be checked +function check_traced_functions() { + local function + + for function in "$@"; do + if ! grep -Fwq "$function" "$SYSFS_TRACING_DIR/trace" ; then + die "Function ($function) did not appear in the trace" + fi + done + + cleanup_tracing +} From 474eecc882aefb53241af09ac54139bf6f700555 Mon Sep 17 00:00:00 2001 From: Filipe Xavier Date: Mon, 24 Mar 2025 19:50:19 -0300 Subject: [PATCH 5/5] selftests: livepatch: test if ftrace can trace a livepatched function This new test makes sure that ftrace can trace a function that was introduced by a livepatch. Signed-off-by: Filipe Xavier Acked-by: Miroslav Benes Acked-by: Joe Lawrence Reviewed-by: Petr Mladek Tested-by: Petr Mladek Link: https://lore.kernel.org/r/20250324-ftrace-sftest-livepatch-v3-2-d9d7cc386c75@gmail.com Signed-off-by: Petr Mladek --- .../selftests/livepatch/test-ftrace.sh | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/testing/selftests/livepatch/test-ftrace.sh b/tools/testing/selftests/livepatch/test-ftrace.sh index fe14f248913ac..094176f1a46ae 100755 --- a/tools/testing/selftests/livepatch/test-ftrace.sh +++ b/tools/testing/selftests/livepatch/test-ftrace.sh @@ -61,4 +61,38 @@ livepatch: '$MOD_LIVEPATCH': unpatching complete % rmmod $MOD_LIVEPATCH" +# - verify livepatch can load +# - check if traces have a patched function +# - reset trace and unload livepatch + +start_test "trace livepatched function and check that the live patch remains in effect" + +FUNCTION_NAME="livepatch_cmdline_proc_show" + +load_lp $MOD_LIVEPATCH +trace_function "$FUNCTION_NAME" + +if [[ "$(cat /proc/cmdline)" == "$MOD_LIVEPATCH: this has been live patched" ]] ; then + log "livepatch: ok" +fi + +check_traced_functions "$FUNCTION_NAME" + +disable_lp $MOD_LIVEPATCH +unload_lp $MOD_LIVEPATCH + +check_result "% insmod test_modules/$MOD_LIVEPATCH.ko +livepatch: enabling patch '$MOD_LIVEPATCH' +livepatch: '$MOD_LIVEPATCH': initializing patching transition +livepatch: '$MOD_LIVEPATCH': starting patching transition +livepatch: '$MOD_LIVEPATCH': completing patching transition +livepatch: '$MOD_LIVEPATCH': patching complete +livepatch: ok +% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled +livepatch: '$MOD_LIVEPATCH': initializing unpatching transition +livepatch: '$MOD_LIVEPATCH': starting unpatching transition +livepatch: '$MOD_LIVEPATCH': completing unpatching transition +livepatch: '$MOD_LIVEPATCH': unpatching complete +% rmmod $MOD_LIVEPATCH" + exit 0