]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
commands: rework bpf devices BPF_F_REPLACE codepath
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 Feb 2021 10:37:55 +0000 (11:37 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 Feb 2021 10:54:33 +0000 (11:54 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/commands.c

index 60315a5ac347f6f7d8baf292753ce72948a1f0be..0c7d6f1fd30144f12a7a8a60de0a393f84a6d1e0 100644 (file)
@@ -1203,6 +1203,8 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
        struct lxc_conf *conf = handler->conf;
        struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
        struct hierarchy *unified = cgroup_ops->unified;
+       int fd_replace = -EBADF;
+       __u32 flags = 0;
        int ret;
        struct lxc_list *it;
        struct device_item *device;
@@ -1260,22 +1262,29 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
        if (ret)
                goto respond;
 
+       flags |= BPF_F_ALLOW_MULTI;
+
        devices_old = cgroup_ops->cgroup2_devices;
-       if (devices_old && devices_old->kernel_fd >= 0)
-               ret = bpf_program_cgroup_attach(devices,
-                                               BPF_CGROUP_DEVICE,
-                                               unified->cgfd_limit,
-                                               devices_old->kernel_fd,
-                                               BPF_F_ALLOW_MULTI | BPF_F_REPLACE);
-       else
-               ret = bpf_program_cgroup_attach(devices,
-                                               BPF_CGROUP_DEVICE,
-                                               unified->cgfd_limit,
-                                               -EBADF,
-                                               BPF_F_ALLOW_MULTI);
+       if (devices_old && devices_old->kernel_fd >= 0) {
+               flags |= BPF_F_REPLACE;
+               fd_replace = devices_old->kernel_fd;
+       }
+
+       ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
+                                       unified->cgfd_limit, fd_replace, flags);
        if (ret)
                goto respond;
 
+       /*
+        * In case we replaced the current bpf program then we don't
+        * need to detach anything. We simply need to close the old fd.
+        */
+       if (devices_old && (flags & BPF_F_REPLACE)) {
+               close_prot_errno_disarm(devices_old->kernel_fd);
+               /* Technically not needed but better safe than segfaulted. */
+               fd_replace = -EBADF;
+       }
+
        /* Replace old bpf program. */
        devices_old = move_ptr(cgroup_ops->cgroup2_devices);
        cgroup_ops->cgroup2_devices = move_ptr(devices);