bpf-program: make bpf_program_load_kernel() idempotent
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Feb 2018 18:19:57 +0000 (19:19 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Feb 2018 15:43:36 +0000 (16:43 +0100)
Let's "seal" off the BPF program as soo as bpf_program_load_kernel() is
called, which allows us to make it idempotent: since the program can't
be modified anymore after being turned into a kernel object it's safe to
shortcut behaviour if called multiple times.

src/basic/bpf-program.c

index 4745950..4c128c6 100644 (file)
@@ -28,6 +28,7 @@
 #include "fd-util.h"
 #include "log.h"
 #include "missing.h"
+#include "util.h"
 
 int bpf_program_new(uint32_t prog_type, BPFProgram **ret) {
         _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
@@ -58,6 +59,9 @@ int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *instructi
 
         assert(p);
 
+        if (p->kernel_fd >= 0) /* don't allow modification after we uploaded things to the kernel */
+                return -EBUSY;
+
         if (!GREEDY_REALLOC(p->instructions, p->allocated, p->n_instructions + count))
                 return -ENOMEM;
 
@@ -72,8 +76,10 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
 
         assert(p);
 
-        if (p->kernel_fd >= 0)
-                return -EBUSY;
+        if (p->kernel_fd >= 0) { /* make this idempotent */
+                memzero(log_buf, log_size);
+                return 0;
+        }
 
         attr = (union bpf_attr) {
                 .prog_type = p->prog_type,