summarylogtreecommitdiffstats
path: root/exported-symbols-hack.diff
blob: 1a29d9ce146e24c734b597db77cd89b142f766a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 <linux/module.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
+#include <linux/version.h>
 #include <linux/xarray.h>
 #include <uapi/linux/winesync.h>
 
 #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 <linux/kprobes.h>
+#else
+#include <linux/kallsyms.h>
+#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);
 }