lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250115082431.5550-9-pmladek@suse.com>
Date: Wed, 15 Jan 2025 09:24:20 +0100
From: Petr Mladek <pmladek@...e.com>
To: Josh Poimboeuf <jpoimboe@...nel.org>,
	Miroslav Benes <mbenes@...e.cz>
Cc: Joe Lawrence <joe.lawrence@...hat.com>,
	Nicolai Stange <nstange@...e.de>,
	live-patching@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Petr Mladek <pmladek@...e.com>
Subject: [PATCH v1 08/19] selftests/livepatch: Move basic tests for livepatching modules

The per-object callbacks have been replaced by per-state callbacks and
will be removed soon.

There are self-tests that attempt to load a live patch with per-object
callbacks and the live-patched module (object) in all possible order
variations.

These order variations are less relevant with per-state callbacks because
they are only invoked when the live patch is enabled or disabled.

However, it is still important to check all possible order variations
to ensure the module is live-patched correctly. The expected state is
validated using two approaches.

First, the "patched" sysfs attribute is checked the same way is in
the sysfs tests.

Second, a new "welcome" parameter has been added to the speaker test
module. By reading this parameter's state, the live-patched function can
be invoked.

Instead of displaying the parameter value via the sysfs interface, the
.read() callback writes a welcome message to the kernel log. This message
is compared with the expected value at the end of the test. This approach
ensures that the self-test attempts to unload the test modules even if
something goes wrong.

Signed-off-by: Petr Mladek <pmladek@...e.com>
---
 tools/testing/selftests/livepatch/Makefile    |   1 +
 .../testing/selftests/livepatch/functions.sh  |  29 +++
 .../selftests/livepatch/test-callbacks.sh     | 226 ------------------
 .../testing/selftests/livepatch/test-order.sh | 226 ++++++++++++++++++
 .../livepatch/test_modules/test_klp_speaker.c |  19 +-
 5 files changed, 274 insertions(+), 227 deletions(-)
 create mode 100755 tools/testing/selftests/livepatch/test-order.sh

diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile
index a080eb54a215..971d0c6f8059 100644
--- a/tools/testing/selftests/livepatch/Makefile
+++ b/tools/testing/selftests/livepatch/Makefile
@@ -5,6 +5,7 @@ TEST_GEN_MODS_DIR := test_modules
 TEST_PROGS_EXTENDED := functions.sh
 TEST_PROGS := \
 	test-livepatch.sh \
+	test-order.sh \
 	test-callbacks.sh \
 	test-shadow-vars.sh \
 	test-state.sh \
diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
index 3f86b89e6ea7..bc1e100e47a7 100644
--- a/tools/testing/selftests/livepatch/functions.sh
+++ b/tools/testing/selftests/livepatch/functions.sh
@@ -279,6 +279,23 @@ function set_pre_patch_ret {
 		die "failed to set pre_patch_ret parameter for $mod module"
 }
 
+# read_module_param(modname, param)
+#	modname - module name which provides the given parameter
+#	param - parameter name to be read
+function read_module_param {
+	local mod="$1"; shift
+	local param="$1"
+
+	log "% cat $SYSFS_MODULE_DIR/$mod/parameters/$param"
+	val=$(cat $SYSFS_MODULE_DIR/$mod/parameters/$param 2>&1)
+	# Log only non-empty values. Some test modules write a message
+	# to the log on its own when reading the parameter, for example,
+	# the "welcome" parameter of the "test_klp_speaker" module.
+	if [[ "$val" != "" ]]; then
+		log "$mod:$param: $ret"
+	fi
+}
+
 function start_test {
 	local test="$1"
 
@@ -353,3 +370,15 @@ function check_sysfs_value() {
 		die "Unexpected value in $path: $expected_value vs. $value"
 	fi
 }
+
+# check_object_patched(livepatch_module, objname, expected_value)
+#	livepatch_module - livepatch module creating the sysfs interface
+#	objname - livepatched object to be checked
+#	expected_value - expected value read from the file
+function check_object_patched() {
+	local livepatch_module="$1"; shift
+	local objname="$1"; shift
+	local expected_value="$1"; shift
+
+	check_sysfs_value "$livepatch_module" "$objname/patched" "$expected_value"
+}
diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh
index a65fd860662e..614ed0aa2e40 100755
--- a/tools/testing/selftests/livepatch/test-callbacks.sh
+++ b/tools/testing/selftests/livepatch/test-callbacks.sh
@@ -11,232 +11,6 @@ MOD_TARGET_BUSY=test_klp_callbacks_busy
 
 setup_config
 
-
-# Test a combination of loading a kernel module and a livepatch that
-# patches a function in the first module.  Load the target module
-# before the livepatch module.  Unload them in the same order.
-#
-# - On livepatch enable, before the livepatch transition starts,
-#   pre-patch callbacks are executed for vmlinux and $MOD_TARGET (those
-#   klp_objects currently loaded).  After klp_objects are patched
-#   according to the klp_patch, their post-patch callbacks run and the
-#   transition completes.
-#
-# - Similarly, on livepatch disable, pre-patch callbacks run before the
-#   unpatching transition starts.  klp_objects are reverted, post-patch
-#   callbacks execute and the transition completes.
-
-start_test "target module before livepatch"
-
-load_mod $MOD_TARGET
-load_lp $MOD_LIVEPATCH
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-unload_mod $MOD_TARGET
-
-check_result "% insmod test_modules/$MOD_TARGET.ko
-$MOD_TARGET: ${MOD_TARGET}_init
-% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': patching complete
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH
-% rmmod $MOD_TARGET
-$MOD_TARGET: ${MOD_TARGET}_exit"
-
-
-# This test is similar to the previous test, but (un)load the livepatch
-# module before the target kernel module.  This tests the livepatch
-# core's module_coming handler.
-#
-# - On livepatch enable, only pre/post-patch callbacks are executed for
-#   currently loaded klp_objects, in this case, vmlinux.
-#
-# - When a targeted module is subsequently loaded, only its
-#   pre/post-patch callbacks are executed.
-#
-# - On livepatch disable, all currently loaded klp_objects' (vmlinux and
-#   $MOD_TARGET) pre/post-unpatch callbacks are executed.
-
-start_test "module_coming notifier"
-
-load_lp $MOD_LIVEPATCH
-load_mod $MOD_TARGET
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-unload_mod $MOD_TARGET
-
-check_result "% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': patching complete
-% insmod test_modules/$MOD_TARGET.ko
-livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_TARGET: ${MOD_TARGET}_init
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH
-% rmmod $MOD_TARGET
-$MOD_TARGET: ${MOD_TARGET}_exit"
-
-
-# Test loading the livepatch after a targeted kernel module, then unload
-# the kernel module before disabling the livepatch.  This tests the
-# livepatch core's module_going handler.
-#
-# - First load a target module, then the livepatch.
-#
-# - When a target module is unloaded, the livepatch is only reverted
-#   from that klp_object ($MOD_TARGET).  As such, only its pre and
-#   post-unpatch callbacks are executed when this occurs.
-#
-# - When the livepatch is disabled, pre and post-unpatch callbacks are
-#   run for the remaining klp_object, vmlinux.
-
-start_test "module_going notifier"
-
-load_mod $MOD_TARGET
-load_lp $MOD_LIVEPATCH
-unload_mod $MOD_TARGET
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-
-check_result "% insmod test_modules/$MOD_TARGET.ko
-$MOD_TARGET: ${MOD_TARGET}_init
-% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': patching complete
-% rmmod $MOD_TARGET
-$MOD_TARGET: ${MOD_TARGET}_exit
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH"
-
-
-# This test is similar to the previous test, however the livepatch is
-# loaded first.  This tests the livepatch core's module_coming and
-# module_going handlers.
-#
-# - First load the livepatch.
-#
-# - When a targeted kernel module is subsequently loaded, only its
-#   pre/post-patch callbacks are executed.
-#
-# - When the target module is unloaded, the livepatch is only reverted
-#   from the $MOD_TARGET klp_object.  As such, only pre and
-#   post-unpatch callbacks are executed when this occurs.
-
-start_test "module_coming and module_going notifiers"
-
-load_lp $MOD_LIVEPATCH
-load_mod $MOD_TARGET
-unload_mod $MOD_TARGET
-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
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': patching complete
-% insmod test_modules/$MOD_TARGET.ko
-livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
-$MOD_LIVEPATCH: pre_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_LIVEPATCH: post_patch_callback: $MOD_TARGET -> [MODULE_STATE_COMING] Full formed, running module_init
-$MOD_TARGET: ${MOD_TARGET}_init
-% rmmod $MOD_TARGET
-$MOD_TARGET: ${MOD_TARGET}_exit
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
-$MOD_LIVEPATCH: post_unpatch_callback: $MOD_TARGET -> [MODULE_STATE_GOING] Going away
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH"
-
-
-# A simple test of loading a livepatch without one of its patch target
-# klp_objects ever loaded ($MOD_TARGET).
-#
-# - Load the livepatch.
-#
-# - As expected, only pre/post-(un)patch handlers are executed for
-#   vmlinux.
-
-start_test "target module not present"
-
-load_lp $MOD_LIVEPATCH
-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
-$MOD_LIVEPATCH: pre_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-$MOD_LIVEPATCH: post_patch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': patching complete
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-$MOD_LIVEPATCH: pre_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-$MOD_LIVEPATCH: post_unpatch_callback: vmlinux
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH"
-
-
 # Test a scenario where a vmlinux pre-patch callback returns a non-zero
 # status (ie, failure).
 #
diff --git a/tools/testing/selftests/livepatch/test-order.sh b/tools/testing/selftests/livepatch/test-order.sh
new file mode 100755
index 000000000000..869b06605597
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test-order.sh
@@ -0,0 +1,226 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2018 Joe Lawrence <joe.lawrence@...hat.com>
+# Copyright (C) 2024 SUSE
+
+. $(dirname $0)/functions.sh
+
+MOD_LIVEPATCH=test_klp_speaker_livepatch
+MOD_TARGET=test_klp_speaker
+
+setup_config
+
+# Test basic livepatch enable/disable functionality when livepatching
+# modules.
+#
+# Loading the livepatch module without the target module being loaded.
+#
+# The transition should succeed. It is basically just a reference for
+# for the following tests.
+
+start_test "module not present"
+
+load_lp $MOD_LIVEPATCH
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "0"
+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
+% 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"
+
+# Load the target module before the livepatch module. Unload them
+# in the reverse order.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of the target module. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "module enable/disable livepatch"
+
+load_mod $MOD_TARGET
+read_module_param $MOD_TARGET welcome
+
+load_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+
+disable_lp $MOD_LIVEPATCH
+unload_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+
+unload_mod $MOD_TARGET
+
+check_result "% insmod test_modules/$MOD_TARGET.ko
+$MOD_TARGET: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker_welcome: Ladies and gentleman, ...
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% rmmod $MOD_TARGET
+$MOD_TARGET: ${MOD_TARGET}_exit"
+
+# Test the module coming hook in the module loader.
+#
+# Load the livepatch before the target module. Unload them in
+# the same order.
+#
+# The livepatch hook in the module loader should print a message
+# about applying the livepatch to the target module.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of the target module. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "module coming hook"
+
+load_lp $MOD_LIVEPATCH
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "0"
+
+load_mod $MOD_TARGET
+read_module_param $MOD_TARGET welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+
+disable_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+
+unload_lp $MOD_LIVEPATCH
+unload_mod $MOD_TARGET
+
+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
+% insmod test_modules/$MOD_TARGET.ko
+livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
+$MOD_TARGET: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker_welcome: Ladies and gentleman, ...
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% rmmod $MOD_LIVEPATCH
+% rmmod $MOD_TARGET
+$MOD_TARGET: ${MOD_TARGET}_exit"
+
+# Test the module going hook in the module loader.
+#
+# The livepatch hook in the module loader should print a message
+# about reverting the livepatch to the target module.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of the target module. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "module going hook"
+
+load_mod $MOD_TARGET
+read_module_param $MOD_TARGET welcome
+
+load_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+
+unload_mod $MOD_TARGET
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "0"
+
+disable_lp $MOD_LIVEPATCH
+unload_lp $MOD_LIVEPATCH
+
+check_result "% insmod test_modules/$MOD_TARGET.ko
+$MOD_TARGET: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_TARGET: speaker_welcome: Hello, World!
+% 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
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker_welcome: Ladies and gentleman, ...
+% rmmod $MOD_TARGET
+$MOD_TARGET: ${MOD_TARGET}_exit
+livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
+% 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"
+
+# Test the module coming and going hooks in the module loader.
+#
+# Load the livepatch before the target module. Unload them in the reverse order.
+#
+# Both livepatch hooks in the module loader should print a message
+# about applying resp. reverting the livepatch to the target module.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of the target module. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "module coming and going hooks"
+
+load_lp $MOD_LIVEPATCH
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "0"
+
+load_mod $MOD_TARGET
+read_module_param $MOD_TARGET welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+
+unload_mod $MOD_TARGET
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "0"
+
+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
+% insmod test_modules/$MOD_TARGET.ko
+livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET'
+$MOD_TARGET: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker_welcome: Ladies and gentleman, ...
+% rmmod $MOD_TARGET
+$MOD_TARGET: ${MOD_TARGET}_exit
+livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET'
+% 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"
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
index b1fb135820b0..22f6e5fcb009 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
@@ -12,14 +12,31 @@
  * The module provides a virtual speaker who can do:
  *
  *    - Start a show with a greeting, see speaker_welcome().
+ *
+ *    - Log the greeting by reading the "welcome" module parameter, see
+ *	welcome_get().
  */
 
 noinline
-static void __always_used speaker_welcome(void)
+static void speaker_welcome(void)
 {
 	pr_info("%s: Hello, World!\n", __func__);
 }
 
+static int welcome_get(char *buffer, const struct kernel_param *kp)
+{
+	speaker_welcome();
+
+	return 0;
+}
+
+static const struct kernel_param_ops welcome_ops = {
+	.get	= welcome_get,
+};
+
+module_param_cb(welcome, &welcome_ops, NULL, 0400);
+MODULE_PARM_DESC(welcome, "Print speaker's welcome message into the kernel log when reading the value.");
+
 static int test_klp_speaker_init(void)
 {
 	pr_info("%s\n", __func__);
-- 
2.47.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ