Skip to content

Instantly share code, notes, and snippets.

@masami256
Last active March 8, 2020 05:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masami256/12e89f8f4377b0055b64b9d615dd558d to your computer and use it in GitHub Desktop.
Save masami256/12e89f8f4377b0055b64b9d615dd558d to your computer and use it in GitHub Desktop.
uname hacks
KERNDIR := /lib/modules/`uname -r`/build
BUILD_DIR := $(shell pwd)
VERBOSE = 0
obj-m := uname-livepatch.o
smallmod-objs := uname-livepatch.o
all:
make -C $(KERNDIR) M=$(BUILD_DIR) KBUILD_VERBOSE=$(VERBOSE) modules
clean:
rm -f *.o
rm -f *.ko
rm -f *.mod.c
rm -f *~
--- ./linux-4.18.0-147.3.1.el8.livepatchtest.x86_64/kernel/sys.c 2019-11-27 09:32:23.000000000 +0900
+++ linux-4.18.0-147.3.1.el8.livepatchtest.x86_64.hack/kernel/sys.c 2020-03-07 23:03:03.146216733 +0900
@@ -1235,12 +1235,18 @@
return ret;
}
+static noinline struct new_utsname *livepatch_test_get_utsname(void)
+{
+ return utsname();
+}
+EXPORT_SYMBOL(livepatch_test_get_utsname);
+
SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
{
int errno = 0;
down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof *name))
+ if (copy_to_user(name, livepatch_test_get_utsname(), sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/livepatch.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/utsname.h>
MODULE_LICENSE("GPL");
MODULE_INFO(livepatch, "Y");
static struct new_utsname *livepatch_get_utsname(void)
{
if (unlikely(!strcmp(current->comm, "uname-test")))
pr_info("livepatch works!!\n");
return utsname();
}
static struct klp_func funcs[] = {
{
.old_name = "livepatch_test_get_utsname",
.new_func = livepatch_get_utsname,
}, { }
};
static struct klp_object objs[] = {
{
.funcs = funcs,
}, { }
};
static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
};
static int uname_livepatch_init(void)
{
int ret;
ret = klp_register_patch(&patch);
if (ret)
return ret;
ret = klp_enable_patch(&patch);
if (ret) {
WARN_ON(klp_unregister_patch(&patch));
return ret;
}
return 0;
}
static void uname_livepatch_exit(void)
{
WARN_ON(klp_unregister_patch(&patch));
}
module_init(uname_livepatch_init);
module_exit(uname_livepatch_exit);
--- ./linux-4.18.0-147.3.1.el8.unametest.x86_64/kernel/sys.c 2019-11-27 09:32:23.000000000 +0900
+++ linux-4.18.0-147.3.1.el8.unametest.x86_64.hack/kernel/sys.c 2020-03-07 21:07:56.727607793 +0900
@@ -1244,6 +1244,10 @@
errno = -EFAULT;
up_read(&uts_sem);
+ if (!strcmp(current->comm, "uname-test"))
+ if (copy_to_user(name->nodename, "livepatched", strlen("livepatched")))
+ errno = -EFAULT;
+
if (!errno && override_release(name->release, sizeof(name->release)))
errno = -EFAULT;
if (!errno && override_architecture(name))
#include <stdio.h>
#include <sys/utsname.h>
int main(int argc, char **argv)
{
struct utsname name = { 0 };
if (uname(&name)) {
perror("uname");
return -1;
}
printf("nodename: %s\n", name.nodename);
return 0;
}
#!/usr/bin/python3
from bcc import BPF
prog = '''
#include <uapi/linux/ptrace.h>
#include <uapi/linux/utsname.h>
void kprobe__sys_newuname(struct pt_regs *ctx, struct new_utsname __user *name)
{
u32 pid;
char comm[256] = { 0 };
pid = bpf_get_current_pid_tgid();
bpf_get_current_comm(&comm, sizeof(comm));
bpf_trace_printk("%d(%s)\\n", pid, comm);
}
'''
print("Ctrl-c to stop")
bpf = BPF(text=prog)
bpf.trace_print()
#!/usr/bin/env stap
%{
#include <linux/string.h>
#include <linux/utsname.h>
%}
function livepatch_get_utsname:long(name:string)
%{
if (!strcmp(STAP_ARG_name, "uname-test"))
pr_info("livepatched\n");
STAP_RETURN(utsname());
%}
probe begin {
printf("start livepatch code. Ctrl-C to stop\n")
}
probe kernel.function("livepatch_test_get_utsname") {
livepatch_get_utsname(execname());
}
probe end {
printf("Done\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment