bpf: add and use bpf_cgroup_devices_attach() helper

parent 928937b1
......@@ -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)
......
......@@ -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");
}
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment