summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-11-08 08:55:54 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-11-19 11:07:31 +0100
commit56e1ba304b006972c85c1e50ddd0cc103988f379 (patch)
treeca42da3e6e61d76df2b594cf2235df4260d6ec0a
parentb06b7ace92c13ca02306a421cd3de195ec688753 (diff)
downloadsystemd-56e1ba304b006972c85c1e50ddd0cc103988f379.tar.gz
core: constify bpf program arrays
In cases where the programs were modified after being initially declared, reorder operations so that the declaration is already in final form. (cherry picked from commit 2899aac46a8d8d5cf1aa5cbf04f755ef7b9f9643)
-rw-r--r--src/core/bpf-devices.c90
-rw-r--r--src/core/bpf-firewall.c10
-rw-r--r--src/test/test-bpf.c2
3 files changed, 48 insertions, 54 deletions
diff --git a/src/core/bpf-devices.c b/src/core/bpf-devices.c
index 9750c4c682..693ff124c5 100644
--- a/src/core/bpf-devices.c
+++ b/src/core/bpf-devices.c
@@ -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()
};
diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
index a637437a5a..d825d00fb7 100644
--- a/src/core/bpf-firewall.c
+++ b/src/core/bpf-firewall.c
@@ -133,7 +133,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),
};
@@ -151,7 +151,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
@@ -187,7 +187,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),
@@ -322,7 +322,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()
};
@@ -796,7 +796,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()
};
diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c
index 6a75221542..f91c43a875 100644
--- a/src/test/test-bpf.c
+++ b/src/test/test-bpf.c
@@ -42,7 +42,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()
};