diff --git a/Makefile b/Makefile index b11347c..0075083 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ifneq (${KERNELRELEASE},) -ccflags-y := -I$(src)/include -DWINESYNC_MINOR=243 +ccflags-y := -include $(src)/defines.h -I$(src)/include -DWINESYNC_MINOR=243 obj-m += src/drivers/misc/winesync.o else KDIR ?= /lib/modules/`uname -r`/build diff --git a/defines.h b/defines.h new file mode 100644 index 0000000..bbf571d --- /dev/null +++ b/defines.h @@ -0,0 +1,3 @@ +#define __set_current_blocked(x) (*p__set_current_blocked)(x) +#define set_user_sigmask(x, y) (*pset_user_sigmask)(x, y) +#define set_compat_user_sigmask(x, y) (*pset_compat_user_sigmask)(x, y) diff --git a/src/drivers/misc/winesync.c b/src/drivers/misc/winesync.c index e9db3b1..db49329 100644 --- a/src/drivers/misc/winesync.c +++ b/src/drivers/misc/winesync.c @@ -11,11 +11,26 @@ #include #include #include +#include #include #include #define WINESYNC_NAME "winesync" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0) +#ifndef CONFIG_KPROBES +#error "Kprobes must be enabled for kernels >= 5.7!" +#endif +#include +#else +#include +#endif + +void (*p__set_current_blocked)(const sigset_t *newset); +int (*pset_user_sigmask)(const sigset_t __user *umask, size_t sigsetsize); +int (*pset_compat_user_sigmask)(const compat_sigset_t __user *umask, + size_t sigsetsize); + enum winesync_type { WINESYNC_TYPE_SEM, WINESYNC_TYPE_MUTEX, @@ -1003,6 +1018,25 @@ static struct miscdevice winesync_misc = { static int __init winesync_init(void) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0) + struct kprobe kp = {0}; + int err; + unsigned long (*kallsyms_lookup_name)(const char *name); + kp.symbol_name = "kallsyms_lookup_name"; + err = register_kprobe(&kp); + if (err) return err; + kallsyms_lookup_name = (void*)kp.addr; + unregister_kprobe(&kp); + if (!kallsyms_lookup_name) return -EINVAL; +#endif + + p__set_current_blocked = (void*)kallsyms_lookup_name("__set_current_blocked"); + if (!p__set_current_blocked) return -EINVAL; + pset_user_sigmask = (void*)kallsyms_lookup_name("set_user_sigmask"); + if (!pset_user_sigmask) return -EINVAL; + pset_compat_user_sigmask = (void*)kallsyms_lookup_name("set_compat_user_sigmask"); + if (!pset_compat_user_sigmask) return -EINVAL; + return misc_register(&winesync_misc); }