]> git.proxmox.com Git - mirror_lxc.git/commitdiff
bpf: add and use bpf_cgroup_devices_attach() helper
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 Feb 2021 12:20:40 +0000 (13:20 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 Feb 2021 12:29:26 +0000 (13:29 +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

index 711a9d7f5493d8d7883ccfc47e0c7ed6e15785f7..64276cde80ed15f5a9263f5b635d7fe18ff2f173 100644 (file)
@@ -3168,12 +3168,8 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
 
 __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct lxc_handler *handler)
 {
-       __do_bpf_program_free struct bpf_program *prog = NULL;
-       int ret;
        struct lxc_conf *conf;
        struct hierarchy *unified;
-       struct lxc_list *it;
-       struct bpf_program *prog_old;
 
        if (!ops)
                return ret_set_errno(false, ENOENT);
@@ -3193,61 +3189,7 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct
            !unified->container_full_path || lxc_list_empty(&conf->devices))
                return true;
 
-       prog = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
-       if (!prog)
-               return log_error_errno(false, ENOMEM, "Failed to create new bpf program");
-
-       ret = bpf_program_init(prog);
-       if (ret)
-               return log_error_errno(false, ENOMEM, "Failed to initialize bpf program");
-
-       bpf_device_set_type(prog, &conf->devices);
-       TRACE("Device bpf %s all devices by default",
-             bpf_device_block_all(prog) ? "blocks" : "allows");
-
-       lxc_list_for_each(it, &conf->devices) {
-               struct device_item *cur = it->elem;
-
-               if (!bpf_device_add(prog, cur)) {
-                       TRACE("Skipping type %c, major %d, minor %d, access %s, allow %d",
-                             cur->type, cur->major, cur->minor, cur->access,
-                             cur->allow);
-                       continue;
-               }
-
-               ret = bpf_program_append_device(prog, cur);
-               if (ret)
-                       return log_error_errno(false, ENOMEM, "Failed to add new rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d",
-                                              cur->type,
-                                              cur->major,
-                                              cur->minor,
-                                              cur->access,
-                                              cur->allow,
-                                              cur->global_rule);
-               TRACE("Added rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d, global_rule %d",
-                     cur->type,
-                     cur->major,
-                     cur->minor,
-                     cur->access,
-                     cur->allow,
-                     cur->global_rule);
-       }
-
-       ret = bpf_program_finalize(prog);
-       if (ret)
-               return log_error_errno(false, ENOMEM, "Failed to finalize bpf program");
-
-       ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE,
-                                       unified->cgfd_limit, -EBADF,
-                                       BPF_F_ALLOW_MULTI);
-       if (ret)
-               return log_error_errno(false, ENOMEM, "Failed to attach bpf program");
-
-       /* Replace old bpf program. */
-       prog_old = move_ptr(ops->cgroup2_devices);
-       ops->cgroup2_devices = move_ptr(prog);
-       prog = move_ptr(prog_old);
-       return true;
+       return bpf_cgroup_devices_attach(ops, &conf->devices);
 }
 
 static bool __cgfsng_delegate_controllers(struct cgroup_ops *ops, const char *cgroup)
index c5afa0ad6d92ca866ad160ea3a1a1dbe9d5c870d..a1c9bc98b2d6d6be938bc41bf1549e33e61da0d4 100644 (file)
@@ -563,3 +563,66 @@ bool bpf_devices_cgroup_supported(void)
 
        return log_trace(true, "The bpf device cgroup is supported");
 }
+
+static struct bpf_program *__bpf_cgroup_devices(struct lxc_list *devices)
+{
+       __do_bpf_program_free struct bpf_program *prog = NULL;
+       int ret;
+       struct lxc_list *it;
+
+       prog = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
+       if (!prog)
+               return syserrno(NULL, "Failed to create new bpf program");
+
+       ret = bpf_program_init(prog);
+       if (ret)
+               return syserrno(NULL, "Failed to initialize bpf program");
+
+       bpf_device_set_type(prog, devices);
+       TRACE("Device bpf %s all devices by default",
+             bpf_device_block_all(prog) ? "blocks" : "allows");
+
+       lxc_list_for_each(it, devices) {
+               struct device_item *cur = it->elem;
+
+               if (!bpf_device_add(prog, cur)) {
+                       TRACE("Skipping rule: type %c, major %d, minor %d, access %s, allow %d",
+                             cur->type, cur->major, cur->minor, cur->access, cur->allow);
+                       continue;
+               }
+
+               ret = bpf_program_append_device(prog, cur);
+               if (ret)
+                       return syserrno(NULL, "Failed adding rule: type %c, major %d, minor %d, access %s, allow %d",
+                                       cur->type, cur->major, cur->minor, cur->access, cur->allow);
+
+               TRACE("Added rule to bpf device program: type %c, major %d, minor %d, access %s, allow %d",
+                     cur->type, cur->major, cur->minor, cur->access, cur->allow);
+       }
+
+       ret = bpf_program_finalize(prog);
+       if (ret)
+               return syserrno(NULL, "Failed to finalize bpf program");
+
+       return move_ptr(prog);
+}
+
+bool bpf_cgroup_devices_attach(struct cgroup_ops *ops, struct lxc_list *devices)
+{
+       __do_bpf_program_free struct bpf_program *prog = NULL;
+       int ret;
+
+       prog = __bpf_cgroup_devices(devices);
+       if (!prog)
+               return syserrno(false, "Failed to create bpf program");
+
+       ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE,
+                                       ops->unified->cgfd_limit, -EBADF,
+                                       BPF_F_ALLOW_MULTI);
+       if (ret)
+               return syserrno(false, "Failed to attach bpf program");
+
+       /* Replace old bpf program. */
+       swap(prog, ops->cgroup2_devices);
+       return log_trace(true, "Attached bpf program");
+}
index 9140872ed7c71f4725fbc67938ec7644e5136ab5..89388934ddba5755c7925660bd49a8a2a4ccdc76 100644 (file)
@@ -97,6 +97,8 @@ __hidden extern void bpf_device_program_free(struct cgroup_ops *ops);
 __hidden extern bool bpf_devices_cgroup_supported(void);
 
 __hidden extern int bpf_list_add_device(struct lxc_conf *conf, struct device_item *device);
+__hidden extern bool bpf_cgroup_devices_attach(struct cgroup_ops *ops,
+                                              struct lxc_list *devices);
 
 define_cleanup_function(struct bpf_program *, bpf_program_free);
 #define __do_bpf_program_free call_cleaner(bpf_program_free)