]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
bpf: use cgroup fd directly instead of paths
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 17 Feb 2021 23:51:14 +0000 (00:51 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 Feb 2021 09:50:03 +0000 (10:50 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/cgroups/cgroup2_devices.c
src/lxc/cgroups/cgroup2_devices.h
src/lxc/commands.c

index 7b4a0b4a679af50a5350c04dfb0091b28884f0df..26e8cb569b906d99b086098ae596c165c86479e9 100644 (file)
@@ -3229,7 +3229,7 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct
                return log_error_errno(false, ENOMEM, "Failed to finalize bpf program");
 
        ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE,
-                                       unified->container_limit_path,
+                                       unified->cgfd_limit,
                                        BPF_F_ALLOW_MULTI);
        if (ret)
                return log_error_errno(false, ENOMEM, "Failed to attach bpf program");
index 31e75485347775691c6d48383a157310b75bad7b..b0af3557091ecfadea6dee0569421bd1d68590df 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "cgroup2_devices.h"
 #include "config.h"
+#include "file_utils.h"
 #include "log.h"
 #include "macro.h"
 #include "memory_utils.h"
@@ -73,7 +74,7 @@ void bpf_program_free(struct bpf_program *prog)
        if (prog->kernel_fd >= 0)
                close(prog->kernel_fd);
        free(prog->instructions);
-       free(prog->attached_path);
+       close_prot_errno_disarm(prog->fd_cgroup);
        free(prog);
 }
 
@@ -185,6 +186,7 @@ struct bpf_program *bpf_program_new(uint32_t prog_type)
 
        prog->prog_type = prog_type;
        prog->kernel_fd = -EBADF;
+       prog->fd_cgroup = -EBADF;
        /*
         * By default a allowlist is used unless the user tells us otherwise.
         */
@@ -360,21 +362,20 @@ static int bpf_program_load_kernel(struct bpf_program *prog)
        return 0;
 }
 
-int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
-                             const char *path, uint32_t flags)
+int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int fd_cgroup,
+                             uint32_t flags)
 {
-       __do_close int fd = -EBADF;
-       __do_free char *copy = NULL;
-       union bpf_attr *attr;
+       __do_close int fd_cgroup_dup = -EBADF;
        int ret;
+       union bpf_attr *attr;
 
-       if (!path || !prog)
-               return ret_set_errno(-1, EINVAL);
+       if (fd_cgroup < 0)
+               return ret_errno(EBADF);
 
        if (flags & ~(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI))
                return log_error_errno(-1, EINVAL, "Invalid flags for bpf program");
 
-       if (prog->attached_path) {
+       if (prog->fd_cgroup >= 0) {
                if (prog->attached_type != type)
                        return log_error_errno(-1, EBUSY, "Wrong type for bpf program");
 
@@ -382,24 +383,20 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
                        return log_error_errno(-1, EBUSY, "Wrong flags for bpf program");
 
                if (flags != BPF_F_ALLOW_OVERRIDE)
-                       return true;
+                       return 0;
        }
 
+       fd_cgroup_dup = dup_cloexec(fd_cgroup);
+       if (fd_cgroup_dup < 0)
+               return -errno;
+
        ret = bpf_program_load_kernel(prog);
        if (ret < 0)
                return log_error_errno(-1, ret, "Failed to load bpf program");
 
-       copy = strdup(path);
-       if (!copy)
-               return log_error_errno(-1, ENOMEM, "Failed to duplicate cgroup path %s", path);
-
-       fd = open(path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
-       if (fd < 0)
-               return log_error_errno(-1, errno, "Failed to open cgroup path %s", path);
-
        attr = &(union bpf_attr){
                .attach_type    = type,
-               .target_fd      = fd,
+               .target_fd      = fd_cgroup_dup,
                .attach_bpf_fd  = prog->kernel_fd,
                .attach_flags   = flags,
        };
@@ -408,49 +405,40 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
        if (ret < 0)
                return log_error_errno(-1, errno, "Failed to attach bpf program");
 
-       free_move_ptr(prog->attached_path, copy);
+       close_move_fd(prog->fd_cgroup, fd_cgroup_dup);
        prog->attached_type = type;
        prog->attached_flags = flags;
 
-       TRACE("Loaded and attached bpf program to cgroup %s", prog->attached_path);
+       TRACE("Loaded and attached bpf program to cgroup %d", prog->fd_cgroup);
        return 0;
 }
 
 int bpf_program_cgroup_detach(struct bpf_program *prog)
 {
-       __do_close int fd = -EBADF;
        int ret;
+       union bpf_attr *attr;
 
        if (!prog)
                return 0;
 
-       if (!prog->attached_path)
+       if (prog->fd_cgroup < 0)
                return 0;
 
-       fd = open(prog->attached_path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
-       if (fd < 0) {
-               if (errno != ENOENT)
-                       return log_error_errno(-1, errno, "Failed to open attach cgroup %s",
-                                              prog->attached_path);
-       } else {
-               union bpf_attr *attr;
-
-               attr = &(union bpf_attr){
-                       .attach_type    = prog->attached_type,
-                       .target_fd      = fd,
-                       .attach_bpf_fd  = prog->kernel_fd,
-               };
+       attr = &(union bpf_attr){
+               .attach_type = prog->attached_type,
+               .target_fd = prog->fd_cgroup,
+               .attach_bpf_fd = prog->kernel_fd,
+       };
 
-               ret = bpf(BPF_PROG_DETACH, attr, sizeof(*attr));
-               if (ret < 0)
-                       return log_error_errno(-1, errno, "Failed to detach bpf program from cgroup %s",
-                                              prog->attached_path);
-       }
+       ret = bpf(BPF_PROG_DETACH, attr, sizeof(*attr));
+       if (ret < 0)
+               return syserrno(-errno, "Failed to detach bpf program from cgroup %d",
+                               prog->fd_cgroup);
 
-        TRACE("Detached bpf program from cgroup %s", prog->attached_path);
-        free_disarm(prog->attached_path);
+       TRACE("Detached bpf program from cgroup %d", prog->fd_cgroup);
+       close_prot_errno_disarm(prog->fd_cgroup);
 
-        return 0;
+       return 0;
 }
 
 void bpf_device_program_free(struct cgroup_ops *ops)
index 2da101ab4c8f5b59d368ca701852bdfbbba731af..40ae1ed64cea0ec68dcd15340edf0c5525dd3f59 100644 (file)
@@ -49,7 +49,7 @@ struct bpf_program {
        struct bpf_insn *instructions;
 #endif /* HAVE_STRUCT_BPF_CGROUP_DEV_CTX */
 
-       char *attached_path;
+       int fd_cgroup;
        int attached_type;
        uint32_t attached_flags;
 };
@@ -59,8 +59,8 @@ __hidden extern struct bpf_program *bpf_program_new(uint32_t prog_type);
 __hidden extern int bpf_program_init(struct bpf_program *prog);
 __hidden extern int bpf_program_append_device(struct bpf_program *prog, struct device_item *device);
 __hidden extern int bpf_program_finalize(struct bpf_program *prog);
-__hidden extern int bpf_program_cgroup_attach(struct bpf_program *prog, int type, const char *path,
-                                             uint32_t flags);
+__hidden extern int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
+                                             int fd_cgroup, uint32_t flags);
 __hidden extern int bpf_program_cgroup_detach(struct bpf_program *prog);
 __hidden extern void bpf_program_free(struct bpf_program *prog);
 __hidden extern void bpf_device_program_free(struct cgroup_ops *ops);
index cb79e6098838844e271465124d38e576430ee89c..cc9a1b3c626bfe24f93d8276c90a29a48c78bb9f 100644 (file)
@@ -1222,6 +1222,9 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
        if (!unified)
                goto respond;
 
+       if (unified->cgfd_mon < 0)
+               goto respond;
+
        ret = bpf_list_add_device(conf, device);
        if (ret < 0)
                goto respond;
@@ -1247,8 +1250,7 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
                goto respond;
 
        ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
-                                       unified->container_full_path,
-                                       BPF_F_ALLOW_MULTI);
+                                       unified->cgfd_mon, BPF_F_ALLOW_MULTI);
        if (ret)
                goto respond;