mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Merge branch 'for-7.1/module-function-test' into for-linus
This commit is contained in:
@@ -8,6 +8,8 @@ MOD_LIVEPATCH1=test_klp_livepatch
|
||||
MOD_LIVEPATCH2=test_klp_syscall
|
||||
MOD_LIVEPATCH3=test_klp_callbacks_demo
|
||||
MOD_REPLACE=test_klp_atomic_replace
|
||||
MOD_TARGET=test_klp_mod_target
|
||||
MOD_TARGET_PATCH=test_klp_mod_patch
|
||||
|
||||
setup_config
|
||||
|
||||
@@ -196,4 +198,102 @@ livepatch: '$MOD_REPLACE': unpatching complete
|
||||
% rmmod $MOD_REPLACE"
|
||||
|
||||
|
||||
# - load a target module that provides /proc/test_klp_mod_target with
|
||||
# original output
|
||||
# - load a livepatch that patches the target module's show function
|
||||
# - verify the proc entry returns livepatched output
|
||||
# - disable and unload the livepatch
|
||||
# - verify the proc entry returns original output again
|
||||
# - unload the target module
|
||||
|
||||
start_test "module function patching"
|
||||
|
||||
load_mod $MOD_TARGET
|
||||
|
||||
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
|
||||
echo -e "FAIL\n\n"
|
||||
die "livepatch kselftest(s) failed"
|
||||
fi
|
||||
|
||||
load_lp $MOD_TARGET_PATCH
|
||||
|
||||
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET_PATCH: this has been live patched" ]] ; then
|
||||
echo -e "FAIL\n\n"
|
||||
die "livepatch kselftest(s) failed"
|
||||
fi
|
||||
|
||||
disable_lp $MOD_TARGET_PATCH
|
||||
unload_lp $MOD_TARGET_PATCH
|
||||
|
||||
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
|
||||
echo -e "FAIL\n\n"
|
||||
die "livepatch kselftest(s) failed"
|
||||
fi
|
||||
|
||||
unload_mod $MOD_TARGET
|
||||
|
||||
check_result "% insmod test_modules/$MOD_TARGET.ko
|
||||
$MOD_TARGET: test_klp_mod_target_init
|
||||
% insmod test_modules/$MOD_TARGET_PATCH.ko
|
||||
livepatch: enabling patch '$MOD_TARGET_PATCH'
|
||||
livepatch: '$MOD_TARGET_PATCH': initializing patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': starting patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': completing patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': patching complete
|
||||
% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
|
||||
livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': unpatching complete
|
||||
% rmmod $MOD_TARGET_PATCH
|
||||
% rmmod $MOD_TARGET
|
||||
$MOD_TARGET: test_klp_mod_target_exit"
|
||||
|
||||
|
||||
# - load a livepatch that targets a not-yet-loaded module
|
||||
# - load the target module: klp_module_coming patches it immediately
|
||||
# - verify the proc entry returns livepatched output
|
||||
# - disable and unload the livepatch
|
||||
# - verify the proc entry returns original output again
|
||||
# - unload the target module
|
||||
|
||||
start_test "module function patching (livepatch first)"
|
||||
|
||||
load_lp $MOD_TARGET_PATCH
|
||||
load_mod $MOD_TARGET
|
||||
|
||||
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET_PATCH: this has been live patched" ]] ; then
|
||||
echo -e "FAIL\n\n"
|
||||
die "livepatch kselftest(s) failed"
|
||||
fi
|
||||
|
||||
disable_lp $MOD_TARGET_PATCH
|
||||
unload_lp $MOD_TARGET_PATCH
|
||||
|
||||
if [[ "$(cat /proc/$MOD_TARGET)" != "$MOD_TARGET: original output" ]] ; then
|
||||
echo -e "FAIL\n\n"
|
||||
die "livepatch kselftest(s) failed"
|
||||
fi
|
||||
|
||||
unload_mod $MOD_TARGET
|
||||
|
||||
check_result "% insmod test_modules/$MOD_TARGET_PATCH.ko
|
||||
livepatch: enabling patch '$MOD_TARGET_PATCH'
|
||||
livepatch: '$MOD_TARGET_PATCH': initializing patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': starting patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': completing patching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': patching complete
|
||||
% insmod test_modules/$MOD_TARGET.ko
|
||||
livepatch: applying patch '$MOD_TARGET_PATCH' to loading module '$MOD_TARGET'
|
||||
$MOD_TARGET: test_klp_mod_target_init
|
||||
% echo 0 > $SYSFS_KLP_DIR/$MOD_TARGET_PATCH/enabled
|
||||
livepatch: '$MOD_TARGET_PATCH': initializing unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': starting unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': completing unpatching transition
|
||||
livepatch: '$MOD_TARGET_PATCH': unpatching complete
|
||||
% rmmod $MOD_TARGET_PATCH
|
||||
% rmmod $MOD_TARGET
|
||||
$MOD_TARGET: test_klp_mod_target_exit"
|
||||
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -8,6 +8,8 @@ obj-m += test_klp_atomic_replace.o \
|
||||
test_klp_callbacks_mod.o \
|
||||
test_klp_kprobe.o \
|
||||
test_klp_livepatch.o \
|
||||
test_klp_mod_patch.o \
|
||||
test_klp_mod_target.o \
|
||||
test_klp_shadow_vars.o \
|
||||
test_klp_state.o \
|
||||
test_klp_state2.o \
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2026 Pablo Hugen <phugen@redhat.com>
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/livepatch.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static int livepatch_mod_target_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "%s: %s\n", THIS_MODULE->name,
|
||||
"this has been live patched");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct klp_func funcs[] = {
|
||||
{
|
||||
.old_name = "test_klp_mod_target_show",
|
||||
.new_func = livepatch_mod_target_show,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static struct klp_object objs[] = {
|
||||
{
|
||||
.name = "test_klp_mod_target",
|
||||
.funcs = funcs,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static struct klp_patch patch = {
|
||||
.mod = THIS_MODULE,
|
||||
.objs = objs,
|
||||
};
|
||||
|
||||
static int test_klp_mod_patch_init(void)
|
||||
{
|
||||
return klp_enable_patch(&patch);
|
||||
}
|
||||
|
||||
static void test_klp_mod_patch_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(test_klp_mod_patch_init);
|
||||
module_exit(test_klp_mod_patch_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_INFO(livepatch, "Y");
|
||||
MODULE_AUTHOR("Pablo Hugen <phugen@redhat.com>");
|
||||
MODULE_DESCRIPTION("Livepatch test: patch for module-provided function");
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2026 Pablo Hugen <phugen@redhat.com>
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static struct proc_dir_entry *pde;
|
||||
|
||||
static noinline int test_klp_mod_target_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "%s: %s\n", THIS_MODULE->name, "original output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_klp_mod_target_init(void)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
pde = proc_create_single("test_klp_mod_target", 0, NULL,
|
||||
test_klp_mod_target_show);
|
||||
if (!pde)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_klp_mod_target_exit(void)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
proc_remove(pde);
|
||||
}
|
||||
|
||||
module_init(test_klp_mod_target_init);
|
||||
module_exit(test_klp_mod_target_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Pablo Hugen <phugen@redhat.com>");
|
||||
MODULE_DESCRIPTION("Livepatch test: target module with proc entry");
|
||||
Reference in New Issue
Block a user