bpf: use cgroup fd directly instead of paths

parent e4f23a0f
...@@ -3227,7 +3227,7 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct ...@@ -3227,7 +3227,7 @@ __cgfsng_ops static bool cgfsng_devices_activate(struct cgroup_ops *ops, struct
return log_error_errno(false, ENOMEM, "Failed to finalize bpf program"); return log_error_errno(false, ENOMEM, "Failed to finalize bpf program");
ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE, ret = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE,
unified->container_limit_path, unified->cgfd_limit,
BPF_F_ALLOW_MULTI); BPF_F_ALLOW_MULTI);
if (ret) if (ret)
return log_error_errno(false, ENOMEM, "Failed to attach bpf program"); return log_error_errno(false, ENOMEM, "Failed to attach bpf program");
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "cgroup2_devices.h" #include "cgroup2_devices.h"
#include "config.h" #include "config.h"
#include "file_utils.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
#include "memory_utils.h" #include "memory_utils.h"
...@@ -73,7 +74,7 @@ void bpf_program_free(struct bpf_program *prog) ...@@ -73,7 +74,7 @@ void bpf_program_free(struct bpf_program *prog)
if (prog->kernel_fd >= 0) if (prog->kernel_fd >= 0)
close(prog->kernel_fd); close(prog->kernel_fd);
free(prog->instructions); free(prog->instructions);
free(prog->attached_path); close_prot_errno_disarm(prog->fd_cgroup);
free(prog); free(prog);
} }
...@@ -185,6 +186,7 @@ struct bpf_program *bpf_program_new(uint32_t prog_type) ...@@ -185,6 +186,7 @@ struct bpf_program *bpf_program_new(uint32_t prog_type)
prog->prog_type = prog_type; prog->prog_type = prog_type;
prog->kernel_fd = -EBADF; prog->kernel_fd = -EBADF;
prog->fd_cgroup = -EBADF;
/* /*
* By default a allowlist is used unless the user tells us otherwise. * By default a allowlist is used unless the user tells us otherwise.
*/ */
...@@ -360,21 +362,20 @@ static int bpf_program_load_kernel(struct bpf_program *prog) ...@@ -360,21 +362,20 @@ static int bpf_program_load_kernel(struct bpf_program *prog)
return 0; return 0;
} }
int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int fd_cgroup,
const char *path, uint32_t flags) uint32_t flags)
{ {
__do_close int fd = -EBADF; __do_close int fd_cgroup_dup = -EBADF;
__do_free char *copy = NULL;
union bpf_attr *attr;
int ret; int ret;
union bpf_attr *attr;
if (!path || !prog) if (fd_cgroup < 0)
return ret_set_errno(-1, EINVAL); return ret_errno(EBADF);
if (flags & ~(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)) if (flags & ~(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI))
return log_error_errno(-1, EINVAL, "Invalid flags for bpf program"); return log_error_errno(-1, EINVAL, "Invalid flags for bpf program");
if (prog->attached_path) { if (prog->fd_cgroup >= 0) {
if (prog->attached_type != type) if (prog->attached_type != type)
return log_error_errno(-1, EBUSY, "Wrong type for bpf program"); return log_error_errno(-1, EBUSY, "Wrong type for bpf program");
...@@ -382,24 +383,20 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, ...@@ -382,24 +383,20 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
return log_error_errno(-1, EBUSY, "Wrong flags for bpf program"); return log_error_errno(-1, EBUSY, "Wrong flags for bpf program");
if (flags != BPF_F_ALLOW_OVERRIDE) if (flags != BPF_F_ALLOW_OVERRIDE)
return true; return 0;
} }
fd_cgroup_dup = dup_cloexec(fd_cgroup);
if (fd_cgroup_dup < 0)
return -errno;
ret = bpf_program_load_kernel(prog); ret = bpf_program_load_kernel(prog);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, ret, "Failed to load bpf program"); return log_error_errno(-1, ret, "Failed to load bpf program");
copy = strdup(path);
if (!copy)
return log_error_errno(-1, ENOMEM, "Failed to duplicate cgroup path %s", path);
fd = open(path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (fd < 0)
return log_error_errno(-1, errno, "Failed to open cgroup path %s", path);
attr = &(union bpf_attr){ attr = &(union bpf_attr){
.attach_type = type, .attach_type = type,
.target_fd = fd, .target_fd = fd_cgroup_dup,
.attach_bpf_fd = prog->kernel_fd, .attach_bpf_fd = prog->kernel_fd,
.attach_flags = flags, .attach_flags = flags,
}; };
...@@ -408,49 +405,40 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, ...@@ -408,49 +405,40 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, "Failed to attach bpf program"); return log_error_errno(-1, errno, "Failed to attach bpf program");
free_move_ptr(prog->attached_path, copy); close_move_fd(prog->fd_cgroup, fd_cgroup_dup);
prog->attached_type = type; prog->attached_type = type;
prog->attached_flags = flags; prog->attached_flags = flags;
TRACE("Loaded and attached bpf program to cgroup %s", prog->attached_path); TRACE("Loaded and attached bpf program to cgroup %d", prog->fd_cgroup);
return 0; return 0;
} }
int bpf_program_cgroup_detach(struct bpf_program *prog) int bpf_program_cgroup_detach(struct bpf_program *prog)
{ {
__do_close int fd = -EBADF;
int ret; int ret;
union bpf_attr *attr;
if (!prog) if (!prog)
return 0; return 0;
if (!prog->attached_path) if (prog->fd_cgroup < 0)
return 0; return 0;
fd = open(prog->attached_path, O_DIRECTORY | O_RDONLY | O_CLOEXEC); attr = &(union bpf_attr){
if (fd < 0) { .attach_type = prog->attached_type,
if (errno != ENOENT) .target_fd = prog->fd_cgroup,
return log_error_errno(-1, errno, "Failed to open attach cgroup %s", .attach_bpf_fd = prog->kernel_fd,
prog->attached_path); };
} else {
union bpf_attr *attr;
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) if (ret < 0)
return log_error_errno(-1, errno, "Failed to detach bpf program from cgroup %s", return syserrno(-errno, "Failed to detach bpf program from cgroup %d",
prog->attached_path); prog->fd_cgroup);
}
TRACE("Detached bpf program from cgroup %s", prog->attached_path); TRACE("Detached bpf program from cgroup %d", prog->fd_cgroup);
free_disarm(prog->attached_path); close_prot_errno_disarm(prog->fd_cgroup);
return 0; return 0;
} }
void bpf_device_program_free(struct cgroup_ops *ops) void bpf_device_program_free(struct cgroup_ops *ops)
......
...@@ -49,7 +49,7 @@ struct bpf_program { ...@@ -49,7 +49,7 @@ struct bpf_program {
struct bpf_insn *instructions; struct bpf_insn *instructions;
#endif /* HAVE_STRUCT_BPF_CGROUP_DEV_CTX */ #endif /* HAVE_STRUCT_BPF_CGROUP_DEV_CTX */
char *attached_path; int fd_cgroup;
int attached_type; int attached_type;
uint32_t attached_flags; uint32_t attached_flags;
}; };
...@@ -59,8 +59,8 @@ __hidden extern struct bpf_program *bpf_program_new(uint32_t prog_type); ...@@ -59,8 +59,8 @@ __hidden extern struct bpf_program *bpf_program_new(uint32_t prog_type);
__hidden extern int bpf_program_init(struct bpf_program *prog); __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_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_finalize(struct bpf_program *prog);
__hidden extern int bpf_program_cgroup_attach(struct bpf_program *prog, int type, const char *path, __hidden extern int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
uint32_t flags); int fd_cgroup, uint32_t flags);
__hidden extern int bpf_program_cgroup_detach(struct bpf_program *prog); __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_program_free(struct bpf_program *prog);
__hidden extern void bpf_device_program_free(struct cgroup_ops *ops); __hidden extern void bpf_device_program_free(struct cgroup_ops *ops);
......
...@@ -1222,6 +1222,9 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re ...@@ -1222,6 +1222,9 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
if (!unified) if (!unified)
goto respond; goto respond;
if (unified->cgfd_mon < 0)
goto respond;
ret = bpf_list_add_device(conf, device); ret = bpf_list_add_device(conf, device);
if (ret < 0) if (ret < 0)
goto respond; goto respond;
...@@ -1247,8 +1250,7 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re ...@@ -1247,8 +1250,7 @@ static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *re
goto respond; goto respond;
ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE, ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
unified->container_full_path, unified->cgfd_mon, BPF_F_ALLOW_MULTI);
BPF_F_ALLOW_MULTI);
if (ret) if (ret)
goto respond; goto respond;
......
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