From d59e29c88ba9f870c04e7cbcc8570360e96384a5 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 29 Jun 2023 08:21:11 +0000 Subject: [PATCH] cgroups: Add BPF program to filter device node access This is currently permitting everything which we don't want to sustain in the long-term. Signed-off-by: Michael Tremer --- src/libpakfire/cgroup.c | 73 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/libpakfire/cgroup.c b/src/libpakfire/cgroup.c index 4c3267cc9..3f6e05854 100644 --- a/src/libpakfire/cgroup.c +++ b/src/libpakfire/cgroup.c @@ -20,18 +20,44 @@ #include #include +#include #include #include #include +// libbpf +#include + #include #include #include #include #include +static char bpf_log_buffer[BPF_LOG_BUF_SIZE]; + #define BUFFER_SIZE 64 * 1024 +// Short form of mov, dst_reg = src_reg +#define BPF_MOV64_IMM(DST, IMM) \ + ((struct bpf_insn){ \ + .code = BPF_ALU64 | BPF_MOV | BPF_K, \ + .dst_reg = DST, \ + .src_reg = 0, \ + .off = 0, \ + .imm = IMM \ + }) + +// Program exit +#define BPF_EXIT_INSN() \ + ((struct bpf_insn){ \ + .code = BPF_JMP | BPF_EXIT, \ + .dst_reg = 0, \ + .src_reg = 0, \ + .off = 0, \ + .imm = 0 \ + }) + enum pakfire_cgroup_controllers { PAKFIRE_CGROUP_CONTROLLER_CPU = (1 << 0), PAKFIRE_CGROUP_CONTROLLER_MEMORY = (1 << 1), @@ -60,6 +86,9 @@ struct pakfire_cgroup { // File descriptor to cgroup int fd; + + // FD to the devices filter program + int devicesfd; }; // Returns true if this is the root cgroup @@ -174,14 +203,51 @@ static void pakfire_cgroup_free(struct pakfire_cgroup* cgroup) { DEBUG(cgroup->pakfire, "Releasing cgroup %s at %p\n", pakfire_cgroup_name(cgroup), cgroup); - // Close the file descriptor + // Close the file descriptors if (cgroup->fd > 0) close(cgroup->fd); + if (cgroup->devicesfd > 0) + close(cgroup->devicesfd); pakfire_unref(cgroup->pakfire); free(cgroup); } +static int pakfire_cgroup_setup_devices(struct pakfire_cgroup* cgroup) { + LIBBPF_OPTS(bpf_prog_load_opts, opts, + // Log Buffer + .log_buf = bpf_log_buffer, + .log_size = sizeof(bpf_log_buffer), + ); + int r; + + struct bpf_insn program[] = { + BPF_MOV64_IMM(BPF_REG_0, 1), // r0 = 1 + BPF_EXIT_INSN(), // return r0 + }; + + // Load the BPF program + r = bpf_prog_load(BPF_PROG_TYPE_CGROUP_DEVICE, NULL, "GPL", + program, sizeof(program) / sizeof(*program), &opts); + if (r < 0) { + ERROR(cgroup->pakfire, "Could not load BPF program: %m\n"); + return r; + } + + // Store the file descriptor + cgroup->devicesfd = r; + + // Attach the program to the cgroup + r = bpf_prog_attach(cgroup->devicesfd, cgroup->fd, + BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI); + if (r) { + ERROR(cgroup->pakfire, "Could not attach BPF program to cgroup: %m\n"); + return r; + } + + return 0; +} + static int pakfire_cgroup_open_root(struct pakfire_cgroup* cgroup) { int fd = open(cgroup->root, O_DIRECTORY|O_PATH|O_CLOEXEC); if (fd < 0) { @@ -537,6 +603,11 @@ int pakfire_cgroup_open(struct pakfire_cgroup** cgroup, goto ERROR; } + // Setup the devices filter + r = pakfire_cgroup_setup_devices(c); + if (r) + goto ERROR; + *cgroup = c; return 0; -- 2.39.5