hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/net/ipv4/bpfilter/sockopt.c
....@@ -1,31 +1,57 @@
11 // SPDX-License-Identifier: GPL-2.0
2
+#include <linux/init.h>
3
+#include <linux/module.h>
24 #include <linux/uaccess.h>
35 #include <linux/bpfilter.h>
46 #include <uapi/linux/bpf.h>
57 #include <linux/wait.h>
68 #include <linux/kmod.h>
9
+#include <linux/fs.h>
10
+#include <linux/file.h>
711
8
-int (*bpfilter_process_sockopt)(struct sock *sk, int optname,
9
- char __user *optval,
10
- unsigned int optlen, bool is_set);
11
-EXPORT_SYMBOL_GPL(bpfilter_process_sockopt);
12
+struct bpfilter_umh_ops bpfilter_ops;
13
+EXPORT_SYMBOL_GPL(bpfilter_ops);
1214
13
-static int bpfilter_mbox_request(struct sock *sk, int optname,
14
- char __user *optval,
15
+void bpfilter_umh_cleanup(struct umd_info *info)
16
+{
17
+ fput(info->pipe_to_umh);
18
+ fput(info->pipe_from_umh);
19
+ put_pid(info->tgid);
20
+ info->tgid = NULL;
21
+}
22
+EXPORT_SYMBOL_GPL(bpfilter_umh_cleanup);
23
+
24
+static int bpfilter_mbox_request(struct sock *sk, int optname, sockptr_t optval,
1525 unsigned int optlen, bool is_set)
1626 {
17
- if (!bpfilter_process_sockopt) {
18
- int err = request_module("bpfilter");
27
+ int err;
28
+ mutex_lock(&bpfilter_ops.lock);
29
+ if (!bpfilter_ops.sockopt) {
30
+ mutex_unlock(&bpfilter_ops.lock);
31
+ request_module("bpfilter");
32
+ mutex_lock(&bpfilter_ops.lock);
1933
20
- if (err)
21
- return err;
22
- if (!bpfilter_process_sockopt)
23
- return -ECHILD;
34
+ if (!bpfilter_ops.sockopt) {
35
+ err = -ENOPROTOOPT;
36
+ goto out;
37
+ }
2438 }
25
- return bpfilter_process_sockopt(sk, optname, optval, optlen, is_set);
39
+ if (bpfilter_ops.info.tgid &&
40
+ thread_group_exited(bpfilter_ops.info.tgid))
41
+ bpfilter_umh_cleanup(&bpfilter_ops.info);
42
+
43
+ if (!bpfilter_ops.info.tgid) {
44
+ err = bpfilter_ops.start();
45
+ if (err)
46
+ goto out;
47
+ }
48
+ err = bpfilter_ops.sockopt(sk, optname, optval, optlen, is_set);
49
+out:
50
+ mutex_unlock(&bpfilter_ops.lock);
51
+ return err;
2652 }
2753
28
-int bpfilter_ip_set_sockopt(struct sock *sk, int optname, char __user *optval,
54
+int bpfilter_ip_set_sockopt(struct sock *sk, int optname, sockptr_t optval,
2955 unsigned int optlen)
3056 {
3157 return bpfilter_mbox_request(sk, optname, optval, optlen, true);
....@@ -39,5 +65,16 @@
3965 if (get_user(len, optlen))
4066 return -EFAULT;
4167
42
- return bpfilter_mbox_request(sk, optname, optval, len, false);
68
+ return bpfilter_mbox_request(sk, optname, USER_SOCKPTR(optval), len,
69
+ false);
4370 }
71
+
72
+static int __init bpfilter_sockopt_init(void)
73
+{
74
+ mutex_init(&bpfilter_ops.lock);
75
+ bpfilter_ops.info.tgid = NULL;
76
+ bpfilter_ops.info.driver_name = "bpfilter_umh";
77
+
78
+ return 0;
79
+}
80
+device_initcall(bpfilter_sockopt_init);