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/pid.h> 6 #include <linux/fs.h> 7 #include <linux/sched/signal.h> 8 #include "bpf_preload.h" 9 10 extern char bpf_preload_umd_start; 11 extern char bpf_preload_umd_end; 12 13 static int preload(struct bpf_preload_info *obj); 14 static int finish(void); 15 16 static struct bpf_preload_ops umd_ops = { 17 .info.driver_name = "bpf_preload", 18 .preload = preload, 19 .finish = finish, 20 .owner = THIS_MODULE, 21 }; 22 23 static int preload(struct bpf_preload_info *obj) 24 { 25 int magic = BPF_PRELOAD_START; 26 loff_t pos = 0; 27 int i, err; 28 ssize_t n; 29 30 err = fork_usermode_driver(&umd_ops.info); 31 if (err) 32 return err; 33 34 /* send the start magic to let UMD proceed with loading BPF progs */ 35 n = kernel_write(umd_ops.info.pipe_to_umh, 36 &magic, sizeof(magic), &pos); 37 if (n != sizeof(magic)) 38 return -EPIPE; 39 40 /* receive bpf_link IDs and names from UMD */ 41 pos = 0; 42 for (i = 0; i < BPF_PRELOAD_LINKS; i++) { 43 n = kernel_read(umd_ops.info.pipe_from_umh, 44 &obj[i], sizeof(*obj), &pos); 45 if (n != sizeof(*obj)) 46 return -EPIPE; 47 } 48 return 0; 49 } 50 51 static int finish(void) 52 { 53 int magic = BPF_PRELOAD_END; 54 struct pid *tgid; 55 loff_t pos = 0; 56 ssize_t n; 57 58 /* send the last magic to UMD. It will do a normal exit. */ 59 n = kernel_write(umd_ops.info.pipe_to_umh, 60 &magic, sizeof(magic), &pos); 61 if (n != sizeof(magic)) 62 return -EPIPE; 63 64 tgid = umd_ops.info.tgid; 65 if (tgid) { 66 wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); 67 umd_cleanup_helper(&umd_ops.info); 68 } 69 return 0; 70 } 71 72 static int __init load_umd(void) 73 { 74 int err; 75 76 err = umd_load_blob(&umd_ops.info, &bpf_preload_umd_start, 77 &bpf_preload_umd_end - &bpf_preload_umd_start); 78 if (err) 79 return err; 80 bpf_preload_ops = &umd_ops; 81 return err; 82 } 83 84 static void __exit fini_umd(void) 85 { 86 struct pid *tgid; 87 88 bpf_preload_ops = NULL; 89 90 /* kill UMD in case it's still there due to earlier error */ 91 tgid = umd_ops.info.tgid; 92 if (tgid) { 93 kill_pid(tgid, SIGKILL, 1); 94 95 wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); 96 umd_cleanup_helper(&umd_ops.info); 97 } 98 umd_unload_blob(&umd_ops.info); 99 } 100 late_initcall(load_umd); 101 module_exit(fini_umd); 102 MODULE_LICENSE("GPL"); 103