add module for testing module patching

A simple kernel module for testing basic kernel module patching.

Just run doit.sh from test/testmod.

Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
Seth Jennings 2014-06-02 17:07:47 -05:00
parent 5f00b0b05f
commit 5b62d5f169
6 changed files with 143 additions and 0 deletions

23
test/testmod/Makefile Normal file
View File

@ -0,0 +1,23 @@
BUILD ?= /lib/modules/$(shell uname -r)/build
testmod.ko: testmod_drv.c
patch < patch
KCFLAGS="-ffunction-sections -fdata-sections" $(MAKE) -C $(BUILD) M=$(PWD) testmod.ko
strip --keep-file-symbols -d testmod_drv.o
cp testmod_drv.o testmod_drv.o.patched
patch -R < patch
KCFLAGS="-ffunction-sections -fdata-sections" $(MAKE) -C $(BUILD) M=$(PWD) testmod.ko
strip --keep-file-symbols -d testmod_drv.o
cp testmod_drv.o testmod_drv.o.orig
$(MAKE) -C $(BUILD) M=$(PWD) clean
$(MAKE) -C $(BUILD) M=$(PWD) testmod.ko
all: testmod.ko
clean:
$(MAKE) -C $(BUILD) M=$(PWD) clean
rm *.orig *.patched
# kbuild rules
obj-m := testmod.o
testmod-y := testmod_drv.o

4
test/testmod/README Normal file
View File

@ -0,0 +1,4 @@
To test, run ./doit.sh from the current directory.
To test on a remote system, set remote system using REMOTE in doit.sh.
Then run ./doit.sh.

27
test/testmod/doit-client.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
#set -x
rmmod testmod 2> /dev/null
rmmod kpatch 2> /dev/null
insmod testmod.ko || exit 1
insmod kpatch.ko || exit 1
if [[ "$(cat /sys/kernel/testmod/value)" != "2" ]]
then
exit 1
fi
insmod kpatch-patch.ko
dmesg | tail
if [[ "$(cat /sys/kernel/testmod/value)" != "3" ]]
then
exit 1
fi
echo 0 > /sys/kernel/kpatch/patches/kpatch_patch/enabled
rmmod kpatch-patch
if [[ "$(cat /sys/kernel/testmod/value)" != "2" ]]
then
exit 1
fi
rmmod kpatch
rmmod testmod
echo "SUCCESS"

34
test/testmod/doit.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
#set -x
# If testing on a remote machine, set it here
# Probably want to use preshared keys.
unset REMOTE
#REMOTE="192.168.100.150"
cd ../../ || exit 1
make clean || exit 1
make || exit 1
cd test/testmod || exit 1
make || exit 1
../../kpatch-build/create-diff-object testmod_drv.o.orig testmod_drv.o.patched testmod.ko output.o || exit 1
cd ../../kmod/patch || exit 1
make clean || exit 1
cp ../../test/testmod/output.o . || exit 1
make || exit 1
cd ../../test/testmod
if [[ -z "$REMOTE" ]]
then
cp ../../kmod/core/kpatch.ko .
cp ../../kmod/patch/kpatch-patch.ko .
sudo ./doit-client.sh
else
scp ../../kmod/core/kpatch.ko root@$REMOTE:~/. || exit 1
scp ../../kmod/patch/kpatch-patch.ko root@$REMOTE:~/. || exit 1
scp testmod.ko root@$REMOTE:~/. || exit 1
scp doit-client.sh root@$REMOTE:~/. || exit 1
ssh root@$REMOTE ./doit-client.sh
fi

11
test/testmod/patch Normal file
View File

@ -0,0 +1,11 @@
--- testmod_drv.c.orig 2014-06-02 16:49:49.428509600 -0500
+++ testmod_drv.c 2014-06-02 16:49:56.973656791 -0500
@@ -11,7 +11,7 @@
static ssize_t value_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", value);
+ return sprintf(buf, "%d\n", value+1);
}
static struct kobj_attribute testmod_value_attr = __ATTR_RO(value);

View File

@ -0,0 +1,44 @@
#define pr_fmt(fmt) "testmod: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
static struct kobject *testmod_kobj;
int value = 2;
static ssize_t value_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", value);
}
static struct kobj_attribute testmod_value_attr = __ATTR_RO(value);
static int testmod_init(void)
{
int ret;
testmod_kobj = kobject_create_and_add("testmod", kernel_kobj);
if (!testmod_kobj)
return -ENOMEM;
ret = sysfs_create_file(testmod_kobj, &testmod_value_attr.attr);
if (ret) {
kobject_put(testmod_kobj);
return ret;
}
return 0;
}
static void testmod_exit(void)
{
sysfs_remove_file(testmod_kobj, &testmod_value_attr.attr);
kobject_put(testmod_kobj);
}
module_init(testmod_init);
module_exit(testmod_exit);
MODULE_LICENSE("GPL");