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-10-pmladek@suse.com>
Date: Wed, 15 Jan 2025 09:24:21 +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 09/19] selftests/livepatch: Convert testing of multiple target modules

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

A selftest previously loaded two livepatched modules to ensure that
the per-object callbacks were called for both.

Although per-state callbacks are only invoked when the live patch is
enabled or disabled, it is still important to verify that multiple objects
can be live-patched.

Convert the test into a generic one by reusing the speaker test module
to create the second target module.

In the second variant, speaker_welcome() will only print "(2)" after
the function name to distinguish it, while keeping the real function name
the same to maintain simplicity.

Signed-off-by: Petr Mladek <pmladek@...e.com>
---
 .../selftests/livepatch/test-callbacks.sh     | 59 ----------------
 .../testing/selftests/livepatch/test-order.sh | 69 +++++++++++++++++++
 .../selftests/livepatch/test_modules/Makefile |  1 +
 .../livepatch/test_modules/test_klp_speaker.c |  8 ++-
 .../test_modules/test_klp_speaker2.c          |  8 +++
 .../test_modules/test_klp_speaker_livepatch.c | 26 ++++++-
 6 files changed, 110 insertions(+), 61 deletions(-)
 create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c

diff --git a/tools/testing/selftests/livepatch/test-callbacks.sh b/tools/testing/selftests/livepatch/test-callbacks.sh
index 614ed0aa2e40..a9bb90920c0a 100755
--- a/tools/testing/selftests/livepatch/test-callbacks.sh
+++ b/tools/testing/selftests/livepatch/test-callbacks.sh
@@ -93,65 +93,6 @@ $MOD_LIVEPATCH: post_unpatch_callback: vmlinux
 livepatch: '$MOD_LIVEPATCH': unpatching complete
 % rmmod $MOD_LIVEPATCH"
 
-
-# Test loading multiple targeted kernel modules.  This test-case is
-# mainly for comparing with the next test-case.
-#
-# - Load a target "busy" kernel module which kicks off a worker function
-#   that immediately exits.
-#
-# - Proceed with loading the livepatch and another ordinary target
-#   module.  Post-patch callbacks are executed and the transition
-#   completes quickly.
-
-start_test "multiple target modules"
-
-load_mod $MOD_TARGET_BUSY block_transition=N
-load_lp $MOD_LIVEPATCH
-load_mod $MOD_TARGET
-unload_mod $MOD_TARGET
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-unload_mod $MOD_TARGET_BUSY
-
-check_result "% insmod test_modules/$MOD_TARGET_BUSY.ko block_transition=N
-$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_init
-$MOD_TARGET_BUSY: busymod_work_func enter
-$MOD_TARGET_BUSY: busymod_work_func exit
-% 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_BUSY -> [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_BUSY -> [MODULE_STATE_LIVE] Normal state
-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
-$MOD_LIVEPATCH: pre_unpatch_callback: $MOD_TARGET_BUSY -> [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_BUSY -> [MODULE_STATE_LIVE] Normal state
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH
-% rmmod $MOD_TARGET_BUSY
-$MOD_TARGET_BUSY: ${MOD_TARGET_BUSY}_exit"
-
-
 # A similar test as the previous one, but force the "busy" kernel module
 # to block the livepatch transition.
 #
diff --git a/tools/testing/selftests/livepatch/test-order.sh b/tools/testing/selftests/livepatch/test-order.sh
index 869b06605597..189132b01bac 100755
--- a/tools/testing/selftests/livepatch/test-order.sh
+++ b/tools/testing/selftests/livepatch/test-order.sh
@@ -7,6 +7,7 @@
 
 MOD_LIVEPATCH=test_klp_speaker_livepatch
 MOD_TARGET=test_klp_speaker
+MOD_TARGET2=test_klp_speaker2
 
 setup_config
 
@@ -224,3 +225,71 @@ livepatch: '$MOD_LIVEPATCH': starting unpatching transition
 livepatch: '$MOD_LIVEPATCH': completing unpatching transition
 livepatch: '$MOD_LIVEPATCH': unpatching complete
 % rmmod $MOD_LIVEPATCH"
+
+# Test loading multiple targeted kernel modules.
+#
+# Load the first target module before the livepatch and the second one later.
+# Disable and unload them in the opposite order.
+#
+# The module loader hooks should print a message about applying/reverting
+# the livepatch for the 2nd module when it is being loaded/unloaded.
+#
+# The expected state is double-checked by reading "welcome" parameter
+# of both target modules. The livepatched variant should be printed
+# when both the target and livepatch modules are loaded.
+
+start_test "multiple target modules"
+
+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"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "0"
+
+load_mod $MOD_TARGET2
+read_module_param $MOD_TARGET2 welcome
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "1"
+
+unload_mod $MOD_TARGET2
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET "1"
+check_object_patched $MOD_LIVEPATCH $MOD_TARGET2 "0"
+
+disable_lp $MOD_LIVEPATCH
+read_module_param $MOD_TARGET welcome
+
+unload_lp $MOD_LIVEPATCH
+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, ...
+% insmod test_modules/$MOD_TARGET2.ko
+livepatch: applying patch '$MOD_LIVEPATCH' to loading module '$MOD_TARGET2'
+$MOD_TARGET2: ${MOD_TARGET}_init
+% cat $SYSFS_MODULE_DIR/$MOD_TARGET2/parameters/welcome
+$MOD_LIVEPATCH: lp_speaker2_welcome(2): Ladies and gentleman, ...
+% rmmod $MOD_TARGET2
+$MOD_TARGET2: ${MOD_TARGET}_exit
+livepatch: reverting patch '$MOD_LIVEPATCH' on unloading module '$MOD_TARGET2'
+% 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"
diff --git a/tools/testing/selftests/livepatch/test_modules/Makefile b/tools/testing/selftests/livepatch/test_modules/Makefile
index 0978c489a67a..72a817d1ddd9 100644
--- a/tools/testing/selftests/livepatch/test_modules/Makefile
+++ b/tools/testing/selftests/livepatch/test_modules/Makefile
@@ -10,6 +10,7 @@ obj-m += test_klp_atomic_replace.o \
 	test_klp_livepatch.o \
 	test_klp_shadow_vars.o \
 	test_klp_speaker.o \
+	test_klp_speaker2.o \
 	test_klp_speaker_livepatch.o \
 	test_klp_state.o \
 	test_klp_state2.o \
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 22f6e5fcb009..92c577addb8e 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker.c
@@ -6,6 +6,10 @@
 #include <linux/module.h>
 #include <linux/printk.h>
 
+#ifndef SPEAKER_ID
+#define SPEAKER_ID ""
+#endif
+
 /**
  * test_klp_speaker - test module for testing misc livepatching features
  *
@@ -15,12 +19,14 @@
  *
  *    - Log the greeting by reading the "welcome" module parameter, see
  *	welcome_get().
+ *
+ *    - Reuse the module source for more speakers, see SPEAKER_ID.
  */
 
 noinline
 static void speaker_welcome(void)
 {
-	pr_info("%s: Hello, World!\n", __func__);
+	pr_info("%s%s: Hello, World!\n", __func__, SPEAKER_ID);
 }
 
 static int welcome_get(char *buffer, const struct kernel_param *kp)
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c
new file mode 100644
index 000000000000..d38ab51414bf
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker2.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2023 SUSE
+
+/* Use versioned function name for livepatched functions */
+#define SPEAKER_ID "(2)"
+
+/* Same module with the same features. */
+#include "test_klp_speaker.c"
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
index 26a8dd15f723..8d7e74a69a5d 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_speaker_livepatch.c
@@ -17,11 +17,23 @@
  *
  *    - Improve the speaker's greeting from "Hello, World!" to
  *	"Ladies and gentleman, ..."
+ *
+ *    - Support more speaker modules, see __lp_speaker_welcome().
  */
 
+static void __lp_speaker_welcome(const char *caller_func, const char *speaker_id)
+{
+	pr_info("%s%s: Ladies and gentleman, ...\n", caller_func, speaker_id);
+}
+
 static void lp_speaker_welcome(void)
 {
-	pr_info("%s: Ladies and gentleman, ...\n", __func__);
+	__lp_speaker_welcome(__func__, "");
+}
+
+static void lp_speaker2_welcome(void)
+{
+	__lp_speaker_welcome(__func__, "(2)");
 }
 
 static struct klp_func test_klp_speaker_funcs[] = {
@@ -32,11 +44,23 @@ static struct klp_func test_klp_speaker_funcs[] = {
 	{ }
 };
 
+static struct klp_func test_klp_speaker2_funcs[] = {
+	{
+		.old_name = "speaker_welcome",
+		.new_func = lp_speaker2_welcome,
+	},
+	{ }
+};
+
 static struct klp_object objs[] = {
 	{
 		.name = "test_klp_speaker",
 		.funcs = test_klp_speaker_funcs,
 	},
+	{
+		.name = "test_klp_speaker2",
+		.funcs = test_klp_speaker2_funcs,
+	},
 	{ }
 };
 
-- 
2.47.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ