From: Christian Brauner Date: Fri, 29 Jan 2021 23:17:14 +0000 (+0100) Subject: cgroups: bpf fixes X-Git-Tag: lxc-5.0.0~312^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcbb9e991ef267e832cffa1407920ac9d1b53c6c;p=thirdparty%2Flxc.git cgroups: bpf fixes Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 4e8512360..ad8410912 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -2963,12 +2963,12 @@ __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) { #ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX - __do_bpf_program_free struct bpf_program *devices = NULL; + __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 *devices_old; + struct bpf_program *prog_old; if (!ops) return ret_set_errno(false, ENOENT); @@ -2988,18 +2988,18 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct !unified->container_full_path || lxc_list_empty(&conf->devices)) return true; - devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE); - if (!devices) + 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(devices); + ret = bpf_program_init(prog); if (ret) return log_error_errno(false, ENOMEM, "Failed to initialize bpf program"); lxc_list_for_each(it, &conf->devices) { struct device_item *cur = it->elem; - ret = bpf_program_append_device(devices, cur); + 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, @@ -3017,20 +3017,20 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct cur->global_rule); } - ret = bpf_program_finalize(devices); + ret = bpf_program_finalize(prog); if (ret) return log_error_errno(false, ENOMEM, "Failed to finalize bpf program"); - ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE, + ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE, unified->container_limit_path, BPF_F_ALLOW_MULTI); if (ret) return log_error_errno(false, ENOMEM, "Failed to attach bpf program"); /* Replace old bpf program. */ - devices_old = move_ptr(ops->cgroup2_devices); - ops->cgroup2_devices = move_ptr(devices); - devices = move_ptr(devices_old); + prog_old = move_ptr(ops->cgroup2_devices); + ops->cgroup2_devices = move_ptr(prog); + prog = move_ptr(prog_old); #endif return true; } diff --git a/src/lxc/cgroups/cgroup2_devices.c b/src/lxc/cgroups/cgroup2_devices.c index 54d333c3f..91b1ff6e3 100644 --- a/src/lxc/cgroups/cgroup2_devices.c +++ b/src/lxc/cgroups/cgroup2_devices.c @@ -179,7 +179,7 @@ struct bpf_program *bpf_program_new(uint32_t prog_type) prog = zalloc(sizeof(struct bpf_program)); if (!prog) - return NULL; + return ret_set_errno(NULL, ENOMEM); prog->prog_type = prog_type; prog->kernel_fd = -EBADF; @@ -194,19 +194,19 @@ struct bpf_program *bpf_program_new(uint32_t prog_type) int bpf_program_init(struct bpf_program *prog) { const struct bpf_insn pre_insn[] = { - /* load device type to r2 */ - BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, access_type)), - BPF_ALU32_IMM(BPF_AND, BPF_REG_2, 0xFFFF), + /* load device type to r2 */ + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, access_type)), + BPF_ALU32_IMM(BPF_AND, BPF_REG_2, 0xFFFF), - /* load access type to r3 */ - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, access_type)), - BPF_ALU32_IMM(BPF_RSH, BPF_REG_3, 16), + /* load access type to r3 */ + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, access_type)), + BPF_ALU32_IMM(BPF_RSH, BPF_REG_3, 16), - /* load major number to r4 */ - BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, major)), + /* load major number to r4 */ + BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, major)), - /* load minor number to r5 */ - BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, minor)), + /* load minor number to r5 */ + BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_1, offsetof(struct bpf_cgroup_dev_ctx, minor)), }; if (!prog) @@ -253,9 +253,9 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi if (!bpf_device_all_access(access_mask)) { struct bpf_insn ins[] = { - BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), - BPF_ALU32_IMM(BPF_AND, BPF_REG_1, access_mask), - BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, jump_nr--), + BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), + BPF_ALU32_IMM(BPF_AND, BPF_REG_1, access_mask), + BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, jump_nr--), }; ret = bpf_program_add_instructions(prog, ins, ARRAY_SIZE(ins)); @@ -265,7 +265,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi if (device_type > 0) { struct bpf_insn ins[] = { - BPF_JMP_IMM(BPF_JNE, BPF_REG_2, device_type, jump_nr--), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, device_type, jump_nr--), }; ret = bpf_program_add_instructions(prog, ins, ARRAY_SIZE(ins)); @@ -275,7 +275,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi if (device->major >= 0) { struct bpf_insn ins[] = { - BPF_JMP_IMM(BPF_JNE, BPF_REG_4, device->major, jump_nr--), + BPF_JMP_IMM(BPF_JNE, BPF_REG_4, device->major, jump_nr--), }; ret = bpf_program_add_instructions(prog, ins, ARRAY_SIZE(ins)); @@ -285,7 +285,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi if (device->minor >= 0) { struct bpf_insn ins[] = { - BPF_JMP_IMM(BPF_JNE, BPF_REG_5, device->minor, jump_nr--), + BPF_JMP_IMM(BPF_JNE, BPF_REG_5, device->minor, jump_nr--), }; ret = bpf_program_add_instructions(prog, ins, ARRAY_SIZE(ins)); @@ -323,7 +323,7 @@ int bpf_program_finalize(struct bpf_program *prog) static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf, __u32 log_size, __u32 log_level) { - union bpf_attr attr; + union bpf_attr *attr; if ((log_size != 0 && !log_buf) || (log_size == 0 && log_buf)) return ret_errno(EINVAL); @@ -333,7 +333,7 @@ static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf, return 0; } - attr = (union bpf_attr){ + attr = &(union bpf_attr){ .prog_type = prog->prog_type, .insns = PTR_TO_UINT64(prog->instructions), .insn_cnt = prog->n_instructions, @@ -343,7 +343,7 @@ static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf, .log_size = log_size, }; - prog->kernel_fd = bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); + prog->kernel_fd = bpf(BPF_PROG_LOAD, attr, sizeof(*attr)); if (prog->kernel_fd < 0) return log_error_errno(-1, errno, "Failed to load bpf program: %s", log_buf ?: "(null)"); @@ -357,7 +357,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, { __do_close int fd = -EBADF; __do_free char *copy = NULL; - union bpf_attr attr; + union bpf_attr *attr; int ret; if (!path || !prog) @@ -389,14 +389,14 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, 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, - .attach_bpf_fd = prog->kernel_fd, - .attach_flags = flags, + attr = &(union bpf_attr){ + .attach_type = type, + .target_fd = fd, + .attach_bpf_fd = prog->kernel_fd, + .attach_flags = flags, }; - ret = bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); + ret = bpf(BPF_PROG_ATTACH, attr, sizeof(*attr)); if (ret < 0) return log_error_errno(-1, errno, "Failed to attach bpf program"); @@ -425,15 +425,15 @@ int bpf_program_cgroup_detach(struct bpf_program *prog) return log_error_errno(-1, errno, "Failed to open attach cgroup %s", prog->attached_path); } else { - union bpf_attr attr; + 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 = fd, + .attach_bpf_fd = prog->kernel_fd, }; - ret = bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); + 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); @@ -523,8 +523,8 @@ bool bpf_devices_cgroup_supported(void) { __do_bpf_program_free struct bpf_program *prog = NULL; const struct bpf_insn dummy[] = { - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), }; int ret; @@ -536,6 +536,10 @@ bool bpf_devices_cgroup_supported(void) if (!prog) return log_trace(false, "Failed to allocate new bpf device cgroup program"); + ret = bpf_program_init(prog); + if (ret) + return log_error_errno(false, ENOMEM, "Failed to initialize bpf program"); + ret = bpf_program_add_instructions(prog, dummy, ARRAY_SIZE(dummy)); if (ret < 0) return log_trace(false, "Failed to add new instructions to bpf device cgroup program");