From 50570326d414bf213f279a791e4ae03210bafa4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Tue, 24 Nov 2020 00:00:01 +0000 Subject: [PATCH] fix kernel modules build after updating linux to v5.9.2 - `dep.c` and `dep2.c`: `debugfs_create_u32` does not return anymore, not sure why: https://unix.stackexchange.com/questions/593983/creating-a-debugfs-file-that-is-used-to-read-write-u32-value/621282#621282 So just doing `debugfs_lookup` for now - vermagic.c: https://github.com/cirosantilli/linux/commit/51161bfc66a68d21f13d15a689b3ea7980457790 prevents its usage in v5.8. Just migrating to `init_utsname` for now - procfs.c: `struct file_operations` moved to a new `struct proc_ops` at: https://github.com/cirosantilli/linux/commit/b567e075139c68c63f1866df23aebe0e86522899 - myprintk.c: `pr_warning` dropped for `pr_warn`: https://github.com/cirosantilli/linux/commit/61ff72f4016804b99d28988a57e65c217f01769d - `poll.c`: `kthread_func` is not defined in kernel, prefix with lkmc to avoid conflict Fix https://github.com/cirosantilli/linux-kernel-module-cheat/issues/136 Fix https://github.com/cirosantilli/linux-kernel-module-cheat/issues/137 --- README.adoc | 19 ++++++++++++++++--- kernel_modules/debugfs.c | 7 +------ kernel_modules/dep.c | 7 ++++--- kernel_modules/dep2.c | 6 +++--- kernel_modules/mmap.c | 15 ++++++++------- kernel_modules/myprintk.c | 2 +- kernel_modules/poll.c | 4 ++-- kernel_modules/procfs.c | 14 ++++++-------- kernel_modules/vermagic.c | 25 ++++++++++++++++++++++++- 9 files changed, 65 insertions(+), 34 deletions(-) diff --git a/README.adoc b/README.adoc index 9736020..ea76d64 100644 --- a/README.adoc +++ b/README.adoc @@ -6765,7 +6765,22 @@ Bibliography: ==== vermagic -Vermagic is a magic string present in the kernel and on <> of kernel modules. It is used to verify that the kernel module was compiled against a compatible kernel version and relevant configuration: +link:kernel_modules/vermagic.c[] + +As of kernel v5.8, you can't use `VERMAGIC_STRING` string from modules anymore as per: https://github.com/cirosantilli/linux/commit/51161bfc66a68d21f13d15a689b3ea7980457790[]. So instead we just showcase `init_utsname`. + +Sample insmod output as of LKMC fa8c2ee521ea83a74a2300e7a3be9f9ab86e2cb6 + 1 aarch64: + +.... +<6>[ 25.180697] sysname = Linux +<6>[ 25.180697] nodename = buildroot +<6>[ 25.180697] release = 5.9.2 +<6>[ 25.180697] version = #1 SMP Thu Jan 1 00:00:00 UTC 1970 +<6>[ 25.180697] machine = aarch64 +<6>[ 25.180697] domainname = (none) +.... + +Vermagic is a magic string present in the kernel and previously visible in <> on kernel modules. It is used to verify that the kernel module was compiled against a compatible kernel version and relevant configuration: .... insmod vermagic.ko @@ -6777,8 +6792,6 @@ Possible dmesg output: VERMAGIC_STRING = 4.17.0 SMP mod_unload modversions .... -Source: link:kernel_modules/vermagic.c[] - If we artificially create a mismatch with `MODULE_INFO(vermagic`, the insmod fails with: .... diff --git a/kernel_modules/debugfs.c b/kernel_modules/debugfs.c index dd87c23..6bbc295 100644 --- a/kernel_modules/debugfs.c +++ b/kernel_modules/debugfs.c @@ -33,17 +33,12 @@ static const struct file_operations fops = { static int myinit(void) { - struct dentry *file; dir = debugfs_create_dir("lkmc_debugfs", 0); if (!dir) { pr_alert("debugfs_create_dir failed"); return -1; } - file = debugfs_create_u32("myfile", S_IRUSR | S_IWUSR, dir, &value); - if (!file) { - pr_alert("debugfs_create_u32 failed"); - return -1; - } + debugfs_create_u32("myfile", S_IRUSR | S_IWUSR, dir, &value); /* Created on the toplevel of the debugfs mount, * and with explicit fops instead of a fixed integer value. diff --git a/kernel_modules/dep.c b/kernel_modules/dep.c index d70e9ce..b9ecd99 100644 --- a/kernel_modules/dep.c +++ b/kernel_modules/dep.c @@ -6,17 +6,18 @@ u32 lkmc_dep = 0; EXPORT_SYMBOL(lkmc_dep); -static struct dentry *debugfs_file; +static char *debugfs_filename = "lkmc_dep"; static int myinit(void) { - debugfs_file = debugfs_create_u32("lkmc_dep", S_IRUSR | S_IWUSR, NULL, &lkmc_dep); + debugfs_create_u32(debugfs_filename, S_IRUSR | S_IWUSR, NULL, &lkmc_dep); return 0; } static void myexit(void) { - debugfs_remove(debugfs_file); + + debugfs_remove(debugfs_lookup(debugfs_filename, NULL)); } module_init(myinit) diff --git a/kernel_modules/dep2.c b/kernel_modules/dep2.c index fbb6d78..21a87c0 100644 --- a/kernel_modules/dep2.c +++ b/kernel_modules/dep2.c @@ -5,17 +5,17 @@ #include extern u32 lkmc_dep; -static struct dentry *debugfs_file; +static char *debugfs_filename = "lkmc_dep2"; static int myinit(void) { - debugfs_file = debugfs_create_u32("lkmc_dep2", S_IRUSR | S_IWUSR, NULL, &lkmc_dep); + debugfs_create_u32(debugfs_filename, S_IRUSR | S_IWUSR, NULL, &lkmc_dep); return 0; } static void myexit(void) { - debugfs_remove(debugfs_file); + debugfs_remove(debugfs_lookup(debugfs_filename, NULL)); } module_init(myinit) diff --git a/kernel_modules/mmap.c b/kernel_modules/mmap.c index f800834..e9aec55 100644 --- a/kernel_modules/mmap.c +++ b/kernel_modules/mmap.c @@ -1,5 +1,6 @@ /* https://cirosantilli.com/linux-kernel-module-cheat#mmap */ +#include /* virt_to_phys */ #include #include #include /* min */ @@ -120,17 +121,17 @@ static int release(struct inode *inode, struct file *filp) return 0; } -static const struct file_operations fops = { - .mmap = mmap, - .open = open, - .release = release, - .read = read, - .write = write, +static const struct proc_ops pops = { + .proc_mmap = mmap, + .proc_open = open, + .proc_release = release, + .proc_read = read, + .proc_write = write, }; static int myinit(void) { - proc_create(filename, 0, NULL, &fops); + proc_create(filename, 0, NULL, &pops); return 0; } diff --git a/kernel_modules/myprintk.c b/kernel_modules/myprintk.c index 55981ae..ce975be 100644 --- a/kernel_modules/myprintk.c +++ b/kernel_modules/myprintk.c @@ -8,7 +8,7 @@ static int myinit(void) pr_alert("pr_alert\n"); pr_crit("pr_crit\n"); pr_err("pr_err"); - pr_warning("pr_warning\n"); + pr_warn("pr_warning\n"); pr_notice("pr_notice\n"); pr_info("pr_info\n"); pr_debug("pr_debug\n"); diff --git a/kernel_modules/poll.c b/kernel_modules/poll.c index 746805f..b311ffa 100644 --- a/kernel_modules/poll.c +++ b/kernel_modules/poll.c @@ -54,7 +54,7 @@ unsigned int poll(struct file *filp, struct poll_table_struct *wait) } } -static int kthread_func(void *data) +static int lkmc_kthread_func(void *data) { while (!kthread_should_stop()) { readbuflen = snprintf( @@ -81,7 +81,7 @@ static int myinit(void) debugfs_file = debugfs_create_file( "lkmc_poll", S_IRUSR | S_IWUSR, NULL, NULL, &fops); init_waitqueue_head(&waitqueue); - kthread = kthread_create(kthread_func, NULL, "mykthread"); + kthread = kthread_create(lkmc_kthread_func, NULL, "mykthread"); wake_up_process(kthread); return 0; } diff --git a/kernel_modules/procfs.c b/kernel_modules/procfs.c index ba8ec07..3d48476 100644 --- a/kernel_modules/procfs.c +++ b/kernel_modules/procfs.c @@ -1,6 +1,5 @@ /* https://cirosantilli.com/linux-kernel-module-cheat#procfs */ -#include #include #include #include /* seq_read, seq_lseek, single_open, single_release */ @@ -19,17 +18,16 @@ static int open(struct inode *inode, struct file *file) return single_open(file, show, NULL); } -static const struct file_operations fops = { - .llseek = seq_lseek, - .open = open, - .owner = THIS_MODULE, - .read = seq_read, - .release = single_release, +static const struct proc_ops pops = { + .proc_lseek = seq_lseek, + .proc_open = open, + .proc_read = seq_read, + .proc_release = single_release, }; static int myinit(void) { - proc_create(filename, 0, NULL, &fops); + proc_create(filename, 0, NULL, &pops); return 0; } diff --git a/kernel_modules/vermagic.c b/kernel_modules/vermagic.c index 6db29a8..faa34c1 100644 --- a/kernel_modules/vermagic.c +++ b/kernel_modules/vermagic.c @@ -2,11 +2,34 @@ #include #include -#include +#include +#if 0 +#include /* VERMAGIC_STRING */ +#endif static int myinit(void) { + struct new_utsname *uts = init_utsname(); + pr_info( + "sysname = %s\n" + "nodename = %s\n" + "release = %s\n" + "version = %s\n" + "machine = %s\n" + "domainname = %s\n", + uts->sysname, + uts->nodename, + uts->release, + uts->version, + uts->machine, + uts->domainname + ); + +#if 0 + /* Possible before v5.8, but was buggy apparently, not sure why: + * https://github.com/cirosantilli/linux/commit/51161bfc66a68d21f13d15a689b3ea7980457790 */ pr_info("VERMAGIC_STRING = " VERMAGIC_STRING "\n"); +#endif /* Nice try, but it is not a member. */ /*pr_info("THIS_MODULE->vermagic = %s\n", THIS_MODULE->vermagic);*/ return 0;