Linux kbuild/kconfig development
 help / color / mirror / Atom feed
From: Lukas Hruska <lhruska@suse.cz>
To: pmladek@suse.com, mbenes@suse.cz, jpoimboe@kernel.org
Cc: joe.lawrence@redhat.com, live-patching@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org,
	mpdesouza@suse.com, lhruska@suse.cz
Subject: [PATCH v3 7/6 DONT_MERGE] selftests: livepatch: Test failing IBT checks crashing the module
Date: Tue, 27 Aug 2024 14:30:52 +0200	[thread overview]
Message-ID: <20240827123052.9002-8-lhruska@suse.cz> (raw)
In-Reply-To: <20240827123052.9002-1-lhruska@suse.cz>

This patch is only an example of how to generate #GP by IBT.
It serves only as an example for those wondering how the Linux behaves
in this case.
Don't merge this patch, because it causes a refcount underflow of the test
module, so it's not possible to unload it.

Signed-off-by: Lukas Hruska <lhruska@suse.cz>
---
 tools/testing/selftests/livepatch/Makefile    |  4 ++
 tools/testing/selftests/livepatch/test-ibt.sh | 57 +++++++++++++++++++
 .../selftests/livepatch/test_modules/Makefile |  2 +
 .../test_modules/test_klp_extern_hello.c      | 20 +++++++
 .../livepatch/test_modules/test_klp_ibt.c     | 51 +++++++++++++++++
 5 files changed, 134 insertions(+)
 create mode 100644 tools/testing/selftests/livepatch/test-ibt.sh
 create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_ibt.c

diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile
index 611ee16bef56..3ef2040e4c50 100644
--- a/tools/testing/selftests/livepatch/Makefile
+++ b/tools/testing/selftests/livepatch/Makefile
@@ -13,6 +13,10 @@ TEST_PROGS := \
 	test-syscall.sh \
 	test-extern.sh
 
+ifdef CONFIG_X86_KERNEL_IBT
+	TEST_PROGS += test-ibt.sh
+endif
+
 TEST_FILES := settings
 
 include ../lib.mk
diff --git a/tools/testing/selftests/livepatch/test-ibt.sh b/tools/testing/selftests/livepatch/test-ibt.sh
new file mode 100644
index 000000000000..c5f49fb7af4d
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test-ibt.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2024 Lukas Hruska <lhruska@suse.cz>
+
+. $(dirname $0)/functions.sh
+
+MOD_LIVEPATCH=test_klp_ibt
+MOD_HELLO=test_klp_extern_hello
+PARAM_HELLO=hello
+
+setup_config
+
+# - load a module to be livepatched
+# - load a livepatch that calls the unused function which does not have endbr64
+#   as its first instruction
+# - unload the livepatch and make sure the patch was removed
+# - unload the module that was livepatched
+
+start_test "livepatch with external symbol"
+
+load_mod $MOD_HELLO
+
+read_module_param $MOD_HELLO $PARAM_HELLO
+
+load_lp $MOD_LIVEPATCH
+
+read_module_param $MOD_HELLO $PARAM_HELLO
+
+disable_lp $MOD_LIVEPATCH
+unload_lp $MOD_LIVEPATCH
+
+read_module_param $MOD_HELLO $PARAM_HELLO
+
+unload_mod $MOD_HELLO
+
+check_result "% insmod test_modules/$MOD_HELLO.ko
+% echo \"$MOD_HELLO/parameters/$PARAM_HELLO: \$(cat /sys/module/$MOD_HELLO/parameters/$PARAM_HELLO)\"
+$MOD_HELLO/parameters/$PARAM_HELLO: Hello from kernel module.
+% 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 \"$MOD_HELLO/parameters/$PARAM_HELLO: \$(cat /sys/module/$MOD_HELLO/parameters/$PARAM_HELLO)\"
+$MOD_HELLO/parameters/$PARAM_HELLO: Hello from livepatched module.
+% echo 0 > /sys/kernel/livepatch/$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
+% echo \"$MOD_HELLO/parameters/$PARAM_HELLO: \$(cat /sys/module/$MOD_HELLO/parameters/$PARAM_HELLO)\"
+$MOD_HELLO/parameters/$PARAM_HELLO: Hello from kernel module.
+% rmmod $MOD_HELLO"
+
+exit 0
diff --git a/tools/testing/selftests/livepatch/test_modules/Makefile b/tools/testing/selftests/livepatch/test_modules/Makefile
index 0d6df14787da..49a22ea90f3a 100644
--- a/tools/testing/selftests/livepatch/test_modules/Makefile
+++ b/tools/testing/selftests/livepatch/test_modules/Makefile
@@ -15,6 +15,8 @@ obj-m += test_klp_atomic_replace.o \
 	test_klp_shadow_vars.o \
 	test_klp_syscall.o
 
+obj-$(CONFIG_X86_KERNEL_IBT) += test_klp_ibt.o
+
 # Ensure that KDIR exists, otherwise skip the compilation
 modules:
 ifneq ("$(wildcard $(KDIR))", "")
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_extern_hello.c b/tools/testing/selftests/livepatch/test_modules/test_klp_extern_hello.c
index 431c55b5849a..37e1cd2cecdb 100644
--- a/tools/testing/selftests/livepatch/test_modules/test_klp_extern_hello.c
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_extern_hello.c
@@ -13,6 +13,26 @@ static int hello_get(char *buffer, const struct kernel_param *kp)
 	return sysfs_emit(buffer, "%s kernel module.\n", hello_msg);
 }
 
+#ifdef CONFIG_X86_KERNEL_IBT
+static __attribute__((nocf_check)) int hello_get_alt(char *buffer, const struct kernel_param *kp)
+{
+	return sysfs_emit(buffer, "%s unused function.\n", hello_msg);
+}
+
+static int fail_get(char *buffer, const struct kernel_param *kp)
+{
+	int __attribute__((nocf_check)) (* volatile klpe_hello_get_alt)(char *, const struct kernel_param *) = hello_get_alt;
+	return (*klpe_hello_get_alt)(buffer, kp);
+}
+
+static const struct kernel_param_ops fail_ops = {
+	.get	= fail_get,
+};
+
+module_param_cb(fail, &fail_ops, NULL, 0400);
+MODULE_PARM_DESC(fail, "Read only parameter failing the reader.");
+#endif
+
 static const struct kernel_param_ops hello_ops = {
 	.get	= hello_get,
 };
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_ibt.c b/tools/testing/selftests/livepatch/test_modules/test_klp_ibt.c
new file mode 100644
index 000000000000..3b76d175d398
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_ibt.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2024 Lukas Hruska <lhruska@suse.cz>
+
+#define pr_fmt(fmt) "test_klp_extern_hello: " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/livepatch.h>
+
+extern int hello_get_alt(char *buffer, const struct kernel_param *kp)
+			KLP_RELOC_SYMBOL(test_klp_extern_hello, test_klp_extern_hello, hello_get_alt);
+
+static int hello_get(char *buffer, const struct kernel_param *kp)
+{
+	return hello_get_alt(buffer, kp);
+}
+
+static struct klp_func funcs[] = {
+	{
+		.old_name = "hello_get",
+		.new_func = hello_get,
+	}, { }
+};
+
+static struct klp_object objs[] = {
+	{
+		.name = "test_klp_extern_hello",
+		.funcs = funcs,
+	}, { }
+};
+
+static struct klp_patch patch = {
+	.mod = THIS_MODULE,
+	.objs = objs,
+};
+
+static int test_klp_extern_init(void)
+{
+	return klp_enable_patch(&patch);
+}
+
+static void test_klp_extern_exit(void)
+{
+}
+
+module_init(test_klp_extern_init);
+module_exit(test_klp_extern_exit);
+MODULE_LICENSE("GPL");
+MODULE_INFO(livepatch, "Y");
+MODULE_AUTHOR("Lukas Hruska <lhruska@suse.cz>");
+MODULE_DESCRIPTION("Livepatch test: external function call with IBT enabled");
-- 
2.46.0


  parent reply	other threads:[~2024-08-27 12:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-27 12:30 [PATCH v3 0/6] livepatch: klp-convert tool - Minimal version Lukas Hruska
2024-08-27 12:30 ` [PATCH v3 1/6] livepatch: Create and include UAPI headers Lukas Hruska
2024-08-27 12:30 ` [PATCH v3 2/6] livepatch: Add klp-convert tool Lukas Hruska
2024-08-27 12:30 ` [PATCH v3 3/6] kbuild/modpost: integrate klp-convert Lukas Hruska
2025-10-08 13:14   ` Petr Mladek
2024-08-27 12:30 ` [PATCH v3 4/6] livepatch: Add sample livepatch module Lukas Hruska
2024-08-28 18:43   ` Jeff Johnson
2024-08-27 12:30 ` [PATCH v3 5/6] documentation: Update on livepatch elf format Lukas Hruska
2024-08-27 12:30 ` [PATCH v3 6/6] selftests: livepatch: Test livepatching function using an external symbol Lukas Hruska
2024-08-27 12:30 ` Lukas Hruska [this message]
2024-09-12 15:15 ` [PATCH v3 0/6] livepatch: klp-convert tool - Minimal version Joe Lawrence
2024-09-13 23:16   ` Josh Poimboeuf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240827123052.9002-8-lhruska@suse.cz \
    --to=lhruska@suse.cz \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=mpdesouza@suse.com \
    --cc=pmladek@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox