From: Christian Brauner Date: Thu, 18 Feb 2021 12:20:40 +0000 (+0100) Subject: bpf: add and use bpf_cgroup_devices_attach() helper X-Git-Tag: lxc-5.0.0~278^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7da502de6a26b8130cbdd36c2337cf3a7c2a996d;p=thirdparty%2Flxc.git bpf: add and use bpf_cgroup_devices_attach() helper Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 711a9d7f5..64276cde8 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -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) diff --git a/src/lxc/cgroups/cgroup2_devices.c b/src/lxc/cgroups/cgroup2_devices.c index c5afa0ad6..a1c9bc98b 100644 --- a/src/lxc/cgroups/cgroup2_devices.c +++ b/src/lxc/cgroups/cgroup2_devices.c @@ -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"); +} diff --git a/src/lxc/cgroups/cgroup2_devices.h b/src/lxc/cgroups/cgroup2_devices.h index 9140872ed..89388934d 100644 --- a/src/lxc/cgroups/cgroup2_devices.h +++ b/src/lxc/cgroups/cgroup2_devices.h @@ -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)