]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - fs/proc/proc_sysctl.c
bpf: Introduce bpf_sysctl_{get,set}_new_value helpers
[mirror_ubuntu-jammy-kernel.git] / fs / proc / proc_sysctl.c
index d653907275419435e4bad20de2f1a704b5c9d6c3..023101c6f0d70e5d3edca285939f6b82233f2d68 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/namei.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/bpf-cgroup.h>
 #include "internal.h"
 
 static const struct dentry_operations proc_sys_dentry_operations;
@@ -569,8 +570,8 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
        struct inode *inode = file_inode(filp);
        struct ctl_table_header *head = grab_header(inode);
        struct ctl_table *table = PROC_I(inode)->sysctl_entry;
+       void *new_buf = NULL;
        ssize_t error;
-       size_t res;
 
        if (IS_ERR(head))
                return PTR_ERR(head);
@@ -588,11 +589,27 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
        if (!table->proc_handler)
                goto out;
 
+       error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, buf, &count,
+                                          &new_buf);
+       if (error)
+               goto out;
+
        /* careful: calling conventions are nasty here */
-       res = count;
-       error = table->proc_handler(table, write, buf, &res, ppos);
+       if (new_buf) {
+               mm_segment_t old_fs;
+
+               old_fs = get_fs();
+               set_fs(KERNEL_DS);
+               error = table->proc_handler(table, write, (void __user *)new_buf,
+                                           &count, ppos);
+               set_fs(old_fs);
+               kfree(new_buf);
+       } else {
+               error = table->proc_handler(table, write, buf, &count, ppos);
+       }
+
        if (!error)
-               error = res;
+               error = count;
 out:
        sysctl_head_finish(head);