From: Christian Brauner Date: Thu, 18 Feb 2021 09:19:27 +0000 (+0100) Subject: bpf: enable helpers to let caller replace existing bpf programs X-Git-Tag: lxc-5.0.0~278^2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d450efcf25c2568075bad9651f5aabdf3df2b17;p=thirdparty%2Flxc.git bpf: enable helpers to let caller replace existing bpf programs Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 26e8cb569..5382befe5 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -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->cgfd_limit, + unified->cgfd_limit, -EBADF, BPF_F_ALLOW_MULTI); if (ret) return log_error_errno(false, ENOMEM, "Failed to attach bpf program"); diff --git a/src/lxc/cgroups/cgroup2_devices.c b/src/lxc/cgroups/cgroup2_devices.c index 435cc0dc2..d9ef697e2 100644 --- a/src/lxc/cgroups/cgroup2_devices.c +++ b/src/lxc/cgroups/cgroup2_devices.c @@ -363,7 +363,7 @@ static int bpf_program_load_kernel(struct bpf_program *prog) } int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int fd_cgroup, - uint32_t flags) + int replace_bpf_fd, uint32_t flags) { __do_close int fd_cgroup_dup = -EBADF; int ret; @@ -372,20 +372,34 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int fd_cgroup, 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 (flags & ~(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI | BPF_F_REPLACE)) + return syserrno_set(-EINVAL, "Invalid flags for bpf program"); + + if (((flags & BPF_F_REPLACE) && replace_bpf_fd < 0) || + (replace_bpf_fd >= 0 && !(flags & BPF_F_REPLACE))) + return syserrno_set(-EINVAL, "Requested to replace bpf program with invalid parameters"); + + /* + * Don't allow the bpf program to be overwritten for now. If we ever + * allow this we need to verify that the attach_flags of the current + * bpf program and the attach_flags of the new program match. + */ + if (flags & BPF_F_ALLOW_OVERRIDE) + INFO("Allowing to override bpf program"); if (prog->fd_cgroup >= 0) { if (prog->attached_type != type) return log_error_errno(-1, EBUSY, "Wrong type for bpf program"); - if (prog->attached_flags != flags) + /* + * For BPF_F_ALLOW_OVERRIDE the flags of the new and old + * program must match. + */ + if ((flags & BPF_F_ALLOW_OVERRIDE) && (prog->attached_flags != flags)) return log_error_errno(-1, EBUSY, "Wrong flags for bpf program"); - - if (flags != BPF_F_ALLOW_OVERRIDE) - return 0; } + /* Leave the caller's fd alone. */ fd_cgroup_dup = dup_cloexec(fd_cgroup); if (fd_cgroup_dup < 0) return -errno; @@ -401,15 +415,19 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int fd_cgroup, .attach_flags = flags, }; + if (flags & BPF_F_REPLACE) + attr->replace_bpf_fd = replace_bpf_fd; + ret = bpf(BPF_PROG_ATTACH, attr, sizeof(*attr)); if (ret < 0) - return log_error_errno(-1, errno, "Failed to attach bpf program"); + return syserrno_set(-errno, "Failed to attach bpf program"); 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 %d", prog->fd_cgroup); + TRACE("Attached bpf program to cgroup %d%s", prog->fd_cgroup, + (flags & BPF_F_REPLACE) ? " and replaced old bpf program" : ""); return 0; } diff --git a/src/lxc/cgroups/cgroup2_devices.h b/src/lxc/cgroups/cgroup2_devices.h index 56eea75a8..c0edea825 100644 --- a/src/lxc/cgroups/cgroup2_devices.h +++ b/src/lxc/cgroups/cgroup2_devices.h @@ -61,7 +61,8 @@ __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, - int fd_cgroup, uint32_t flags); + int fd_cgroup, int replace_bpf_fd, + 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); diff --git a/src/lxc/commands.c b/src/lxc/commands.c index cc9a1b3c6..2fbe73f71 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -1250,7 +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->cgfd_mon, BPF_F_ALLOW_MULTI); + unified->cgfd_mon, -EBADF, BPF_F_ALLOW_MULTI); if (ret) goto respond;