1 // SPDX-License-Identifier: GPL-2.0 2 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 3 #include <linux/init.h> 4 #include <linux/module.h> 5 #include <linux/umh.h> 6 #include <linux/bpfilter.h> 7 #include <linux/sched.h> 8 #include <linux/sched/signal.h> 9 #include <linux/fs.h> 10 #include <linux/file.h> 11 #include "msgfmt.h" 12 13 #define UMH_start _binary_net_bpfilter_bpfilter_umh_start 14 #define UMH_end _binary_net_bpfilter_bpfilter_umh_end 15 16 extern char UMH_start; 17 extern char UMH_end; 18 19 static struct umh_info info; 20 /* since ip_getsockopt() can run in parallel, serialize access to umh */ 21 static DEFINE_MUTEX(bpfilter_lock); 22 23 static void shutdown_umh(struct umh_info *info) 24 { 25 struct task_struct *tsk; 26 27 if (!info->pid) 28 return; 29 tsk = pid_task(find_vpid(info->pid), PIDTYPE_PID); 30 if (tsk) 31 force_sig(SIGKILL, tsk); 32 fput(info->pipe_to_umh); 33 fput(info->pipe_from_umh); 34 info->pid = 0; 35 } 36 37 static void __stop_umh(void) 38 { 39 if (IS_ENABLED(CONFIG_INET)) { 40 bpfilter_process_sockopt = NULL; 41 shutdown_umh(&info); 42 } 43 } 44 45 static void stop_umh(void) 46 { 47 mutex_lock(&bpfilter_lock); 48 __stop_umh(); 49 mutex_unlock(&bpfilter_lock); 50 } 51 52 static int __bpfilter_process_sockopt(struct sock *sk, int optname, 53 char __user *optval, 54 unsigned int optlen, bool is_set) 55 { 56 struct mbox_request req; 57 struct mbox_reply reply; 58 loff_t pos; 59 ssize_t n; 60 int ret = -EFAULT; 61 62 req.is_set = is_set; 63 req.pid = current->pid; 64 req.cmd = optname; 65 req.addr = (long)optval; 66 req.len = optlen; 67 mutex_lock(&bpfilter_lock); 68 if (!info.pid) 69 goto out; 70 n = __kernel_write(info.pipe_to_umh, &req, sizeof(req), &pos); 71 if (n != sizeof(req)) { 72 pr_err("write fail %zd\n", n); 73 __stop_umh(); 74 ret = -EFAULT; 75 goto out; 76 } 77 pos = 0; 78 n = kernel_read(info.pipe_from_umh, &reply, sizeof(reply), &pos); 79 if (n != sizeof(reply)) { 80 pr_err("read fail %zd\n", n); 81 __stop_umh(); 82 ret = -EFAULT; 83 goto out; 84 } 85 ret = reply.status; 86 out: 87 mutex_unlock(&bpfilter_lock); 88 return ret; 89 } 90 91 static int __init load_umh(void) 92 { 93 int err; 94 95 /* fork usermode process */ 96 err = fork_usermode_blob(&UMH_start, &UMH_end - &UMH_start, &info); 97 if (err) 98 return err; 99 pr_info("Loaded bpfilter_umh pid %d\n", info.pid); 100 101 /* health check that usermode process started correctly */ 102 if (__bpfilter_process_sockopt(NULL, 0, 0, 0, 0) != 0) { 103 stop_umh(); 104 return -EFAULT; 105 } 106 if (IS_ENABLED(CONFIG_INET)) 107 bpfilter_process_sockopt = &__bpfilter_process_sockopt; 108 109 return 0; 110 } 111 112 static void __exit fini_umh(void) 113 { 114 stop_umh(); 115 } 116 module_init(load_umh); 117 module_exit(fini_umh); 118 MODULE_LICENSE("GPL"); 119