]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: constify bpf program arrays
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 8 Nov 2019 07:55:54 +0000 (08:55 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 10 Nov 2019 22:22:14 +0000 (23:22 +0100)
In cases where the programs were modified after being initially declared,
reorder operations so that the declaration is already in final form.

src/core/bpf-devices.c
src/core/bpf-firewall.c
src/test/test-bpf.c

index 9750c4c68277d6a0045b2b1655d5819ef95c69d2..693ff124c52fd38d2a8bfc90097345dca2a55a11 100644 (file)
@@ -30,15 +30,6 @@ static int bpf_access_type(const char *acc) {
 }
 
 int cgroup_bpf_whitelist_device(BPFProgram *prog, int type, int major, int minor, const char *acc) {
-        struct bpf_insn insn[] = {
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 6), /* compare device type */
-                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
-                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, 0),
-                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 3), /* compare access type */
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_4, major, 2), /* compare major */
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_5, minor, 1), /* compare minor */
-                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
-        };
         int r, access;
 
         assert(prog);
@@ -48,7 +39,15 @@ int cgroup_bpf_whitelist_device(BPFProgram *prog, int type, int major, int minor
         if (access <= 0)
                 return -EINVAL;
 
-        insn[2].imm = access;
+        const struct bpf_insn insn[] = {
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 6), /* compare device type */
+                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
+                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, access),
+                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 3), /* compare access type */
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_4, major, 2), /* compare major */
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_5, minor, 1), /* compare minor */
+                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
+        };
 
         r = bpf_program_add_instructions(prog, insn, ELEMENTSOF(insn));
         if (r < 0)
@@ -58,14 +57,6 @@ int cgroup_bpf_whitelist_device(BPFProgram *prog, int type, int major, int minor
 }
 
 int cgroup_bpf_whitelist_major(BPFProgram *prog, int type, int major, const char *acc) {
-        struct bpf_insn insn[] = {
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 5), /* compare device type */
-                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
-                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, 0),
-                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 2), /* compare access type */
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_4, major, 1), /* compare major */
-                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
-        };
         int r, access;
 
         assert(prog);
@@ -75,7 +66,14 @@ int cgroup_bpf_whitelist_major(BPFProgram *prog, int type, int major, const char
         if (access <= 0)
                 return -EINVAL;
 
-        insn[2].imm = access;
+        const struct bpf_insn insn[] = {
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 5), /* compare device type */
+                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
+                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, access),
+                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 2), /* compare access type */
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_4, major, 1), /* compare major */
+                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
+        };
 
         r = bpf_program_add_instructions(prog, insn, ELEMENTSOF(insn));
         if (r < 0)
@@ -85,13 +83,6 @@ int cgroup_bpf_whitelist_major(BPFProgram *prog, int type, int major, const char
 }
 
 int cgroup_bpf_whitelist_class(BPFProgram *prog, int type, const char *acc) {
-        struct bpf_insn insn[] = {
-                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 5), /* compare device type */
-                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
-                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, 0),
-                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 1), /* compare access type */
-                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
-        };
         int r, access;
 
         assert(prog);
@@ -101,7 +92,13 @@ int cgroup_bpf_whitelist_class(BPFProgram *prog, int type, const char *acc) {
         if (access <= 0)
                 return -EINVAL;
 
-        insn[2].imm = access;
+        const struct bpf_insn insn[] = {
+                BPF_JMP_IMM(BPF_JNE, BPF_REG_2, type, 5), /* compare device type */
+                BPF_MOV32_REG(BPF_REG_1, BPF_REG_3), /* calculate access type */
+                BPF_ALU32_IMM(BPF_AND, BPF_REG_1, access),
+                BPF_JMP_REG(BPF_JNE, BPF_REG_1, BPF_REG_3, 1), /* compare access type */
+                BPF_JMP_A(PASS_JUMP_OFF), /* jump to PASS */
+        };
 
         r = bpf_program_add_instructions(prog, insn, ELEMENTSOF(insn));
         if (r < 0)
@@ -111,7 +108,7 @@ int cgroup_bpf_whitelist_class(BPFProgram *prog, int type, const char *acc) {
 }
 
 int cgroup_init_device_bpf(BPFProgram **ret, CGroupDevicePolicy policy, bool whitelist) {
-        struct bpf_insn pre_insn[] = {
+        const struct bpf_insn pre_insn[] = {
                 /* load device type to r2 */
                 BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1,
                             offsetof(struct bpf_cgroup_dev_ctx, access_type)),
@@ -154,19 +151,6 @@ int cgroup_init_device_bpf(BPFProgram **ret, CGroupDevicePolicy policy, bool whi
 }
 
 int cgroup_apply_device_bpf(Unit *u, BPFProgram *prog, CGroupDevicePolicy policy, bool whitelist) {
-        struct bpf_insn post_insn[] = {
-                /* return DENY */
-                BPF_MOV64_IMM(BPF_REG_0, 0),
-                BPF_JMP_A(1),
-
-        };
-
-        struct bpf_insn exit_insn[] = {
-                /* else return ALLOW */
-                BPF_MOV64_IMM(BPF_REG_0, 1),
-                BPF_EXIT_INSN()
-        };
-
         _cleanup_free_ char *path = NULL;
         int r;
 
@@ -176,23 +160,33 @@ int cgroup_apply_device_bpf(Unit *u, BPFProgram *prog, CGroupDevicePolicy policy
                 return 0;
         }
 
-        if (policy != CGROUP_STRICT || whitelist) {
-                size_t off;
+        const bool deny_everything = policy == CGROUP_STRICT && !whitelist;
 
+        const struct bpf_insn post_insn[] = {
+                /* return DENY */
+                BPF_MOV64_IMM(BPF_REG_0, 0),
+                BPF_JMP_A(1),
+        };
+
+        const struct bpf_insn exit_insn[] = {
+                /* finally return DENY if deny_everything else ALLOW */
+                BPF_MOV64_IMM(BPF_REG_0, deny_everything ? 0 : 1),
+                BPF_EXIT_INSN()
+        };
+
+        if (!deny_everything) {
                 r = bpf_program_add_instructions(prog, post_insn, ELEMENTSOF(post_insn));
                 if (r < 0)
                         return log_error_errno(r, "Extending device control BPF program failed: %m");
 
                 /* Fixup PASS_JUMP_OFF jump offsets. */
-                for (off = 0; off < prog->n_instructions; off++) {
+                for (size_t off = 0; off < prog->n_instructions; off++) {
                         struct bpf_insn *ins = &prog->instructions[off];
 
                         if (ins->code == (BPF_JMP | BPF_JA) && ins->off == PASS_JUMP_OFF)
                                 ins->off = prog->n_instructions - off - 1;
                 }
-        } else
-                /* Explicitly forbid everything. */
-                exit_insn[0].imm = 0;
+        }
 
         r = bpf_program_add_instructions(prog, exit_insn, ELEMENTSOF(exit_insn));
         if (r < 0)
@@ -216,7 +210,7 @@ int cgroup_apply_device_bpf(Unit *u, BPFProgram *prog, CGroupDevicePolicy policy
 }
 
 int bpf_devices_supported(void) {
-        struct bpf_insn trivial[] = {
+        const struct bpf_insn trivial[] = {
                 BPF_MOV64_IMM(BPF_REG_0, 1),
                 BPF_EXIT_INSN()
         };
index 424162f4458d947fa8eaae3946fb946d3fd3ce23..96c1a28b4fd02adb70e939b564afec32c54c11fb 100644 (file)
@@ -132,7 +132,7 @@ static int add_instructions_for_ip_any(
 
         assert(p);
 
-        struct bpf_insn insn[] = {
+        const struct bpf_insn insn[] = {
                 BPF_ALU32_IMM(BPF_OR, BPF_REG_8, verdict),
         };
 
@@ -150,7 +150,7 @@ static int bpf_firewall_compile_bpf(
                 bool ip_allow_any,
                 bool ip_deny_any) {
 
-        struct bpf_insn pre_insn[] = {
+        const struct bpf_insn pre_insn[] = {
                 /*
                  * When the eBPF program is entered, R1 contains the address of the skb.
                  * However, R1-R5 are scratch registers that are not preserved when calling
@@ -186,7 +186,7 @@ static int bpf_firewall_compile_bpf(
          * This means that if both ACCESS_DENIED and ACCESS_ALLOWED are set, the packet
          * is allowed to pass.
          */
-        struct bpf_insn post_insn[] = {
+        const struct bpf_insn post_insn[] = {
                 BPF_MOV64_IMM(BPF_REG_0, 1),
                 BPF_JMP_IMM(BPF_JNE, BPF_REG_8, ACCESS_DENIED, 1),
                 BPF_MOV64_IMM(BPF_REG_0, 0),
@@ -321,7 +321,7 @@ static int bpf_firewall_compile_bpf(
                  * Exit from the eBPF program, R0 contains the verdict.
                  * 0 means the packet is denied, 1 means the packet may pass.
                  */
-                struct bpf_insn insn[] = {
+                const struct bpf_insn insn[] = {
                         BPF_EXIT_INSN()
                 };
 
@@ -795,7 +795,7 @@ int bpf_firewall_reset_accounting(int map_fd) {
 static int bpf_firewall_unsupported_reason = 0;
 
 int bpf_firewall_supported(void) {
-        struct bpf_insn trivial[] = {
+        const struct bpf_insn trivial[] = {
                 BPF_MOV64_IMM(BPF_REG_0, 1),
                 BPF_EXIT_INSN()
         };
index d333466ab8ece9254d24d77ea8b74f218347782e..49dc0b7e8927c6c5a20e44821ba97801397fc461 100644 (file)
@@ -41,7 +41,7 @@ static bool can_memlock(void) {
 }
 
 int main(int argc, char *argv[]) {
-        struct bpf_insn exit_insn[] = {
+        const struct bpf_insn exit_insn[] = {
                 BPF_MOV64_IMM(BPF_REG_0, 0), /* drop */
                 BPF_EXIT_INSN()
         };