aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--cooker/filter.c126
-rw-r--r--cooker/filter.h31
2 files changed, 65 insertions, 92 deletions
diff --git a/cooker/filter.c b/cooker/filter.c
index bffdfe4..c7e0ee4 100644
--- a/cooker/filter.c
+++ b/cooker/filter.c
@@ -324,15 +324,14 @@ static unsigned int eq(struct sock_filter filter[],
case BPF_U64:
hi = get_hi(field->value.v64);
lo = get_lo(field->value.v64);
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)EQ(lo, 0, jfalse);
- filter[size++] = (struct sock_filter)LOAD(HI_ARG(field->arg));
- filter[size++] = (struct sock_filter)EQ(hi, jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = EQ(lo, 0, jfalse);
+ filter[size++] = LOAD(HI_ARG(field->arg));
+ filter[size++] = EQ(hi, jtrue, jfalse);
break;
case BPF_U32:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)EQ(
- field->value.v32, jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = EQ(field->value.v32, jtrue, jfalse);
break;
}
@@ -350,15 +349,14 @@ static unsigned int gt(struct sock_filter filter[],
case BPF_U64:
hi = get_hi(field->value.v64);
lo = get_lo(field->value.v64);
- filter[size++] = (struct sock_filter)LOAD(HI_ARG(field->arg));
- filter[size++] = (struct sock_filter)GT(hi, jtrue + 2, 0);
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)GT(lo, jtrue, jfalse);
+ filter[size++] = LOAD(HI_ARG(field->arg));
+ filter[size++] = GT(hi, jtrue + 2, 0);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = GT(lo, jtrue, jfalse);
break;
case BPF_U32:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)GT(
- field->value.v32, jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = GT(field->value.v32, jtrue, jfalse);
break;
}
@@ -376,15 +374,14 @@ static unsigned int lt(struct sock_filter filter[],
case BPF_U64:
hi = get_hi(field->value.v64);
lo = get_lo(field->value.v64);
- filter[size++] = (struct sock_filter)LOAD(HI_ARG(field->arg));
- filter[size++] = (struct sock_filter)LT(hi, jtrue + 2, jfalse);
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)LT(lo, jtrue, jfalse);
+ filter[size++] = LOAD(HI_ARG(field->arg));
+ filter[size++] = LT(hi, jtrue + 2, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = LT(lo, jtrue, jfalse);
break;
case BPF_U32:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)LT(
- field->value.v32, jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = LT(field->value.v32, jtrue, jfalse);
break;
}
@@ -420,23 +417,17 @@ static unsigned int and_eq(struct sock_filter filter[],
switch (field->type) {
case BPF_U64:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)AND(
- get_lo(field->op2.v64));
- filter[size++] = (struct sock_filter)EQ(
- get_lo(field->value.v64), 0, jfalse);
- filter[size++] = (struct sock_filter)LOAD(HI_ARG(field->arg));
- filter[size++] = (struct sock_filter)AND(
- get_hi(field->op2.v64));
- filter[size++] = (struct sock_filter)EQ(
- get_hi(field->value.v64), jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = AND(get_lo(field->op2.v64));
+ filter[size++] = EQ(get_lo(field->value.v64), 0, jfalse);
+ filter[size++] = LOAD(HI_ARG(field->arg));
+ filter[size++] = AND(get_hi(field->op2.v64));
+ filter[size++] = EQ(get_hi(field->value.v64), jtrue, jfalse);
break;
case BPF_U32:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] =
- (struct sock_filter)AND(field->op2.v32);
- filter[size++] = (struct sock_filter)EQ(
- field->value.v32, jtrue, jfalse);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = AND(field->op2.v32);
+ filter[size++] = EQ(field->value.v32, jtrue, jfalse);
break;
}
@@ -451,23 +442,17 @@ static unsigned int and_ne(struct sock_filter filter[],
switch (field->type) {
case BPF_U64:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] = (struct sock_filter)AND(
- get_lo(field->op2.v64));
- filter[size++] = (struct sock_filter)EQ(
- get_lo(field->value.v64), 0, jtrue + 3);
- filter[size++] = (struct sock_filter)LOAD(HI_ARG(field->arg));
- filter[size++] = (struct sock_filter)AND(
- get_hi(field->op2.v64));
- filter[size++] = (struct sock_filter)EQ(
- get_hi(field->value.v64), jfalse, jtrue);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = AND(get_lo(field->op2.v64));
+ filter[size++] = EQ(get_lo(field->value.v64), 0, jtrue + 3);
+ filter[size++] = LOAD(HI_ARG(field->arg));
+ filter[size++] = AND(get_hi(field->op2.v64));
+ filter[size++] = EQ(get_hi(field->value.v64), jfalse, jtrue);
break;
case BPF_U32:
- filter[size++] = (struct sock_filter)LOAD(LO_ARG(field->arg));
- filter[size++] =
- (struct sock_filter)AND(field->op2.v32);
- filter[size++] = (struct sock_filter)EQ(
- field->value.v32, jfalse, jtrue);
+ filter[size++] = LOAD(LO_ARG(field->arg));
+ filter[size++] = AND(field->op2.v32);
+ filter[size++] = EQ(field->value.v32, jfalse, jtrue);
break;
}
@@ -530,8 +515,8 @@ static unsigned int insert_args(struct sock_filter filter[], long nr)
/* If there were no arguments for this entry, then we don't need
* to add the notification */
if (n_checks > 0)
- filter[size++] = (struct sock_filter)BPF_STMT(
- BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
+ filter[size++] = STMT(BPF_RET | BPF_K,
+ SECCOMP_RET_ALLOW);
}
return size;
@@ -556,16 +541,14 @@ unsigned int filter_build(struct sock_filter filter[], unsigned n)
/* Pre */
/* cppcheck-suppress badBitmaskCheck */
- filter[size++] = (struct sock_filter)BPF_STMT(
- BPF_LD | BPF_W | BPF_ABS,
- (offsetof(struct seccomp_data, arch)));
- filter[size++] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,
- SEITAN_AUDIT_ARCH, 1, 0);
- filter[size++] = (struct sock_filter)BPF_STMT(BPF_RET | BPF_K,
- SECCOMP_RET_ALLOW);
+ filter[size++] = STMT(BPF_LD | BPF_W | BPF_ABS,
+ offsetof(struct seccomp_data, arch));
+ filter[size++] = JUMP(BPF_JMP | BPF_JEQ | BPF_K,
+ SEITAN_AUDIT_ARCH, 1, 0);
+ filter[size++] = STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
/* cppcheck-suppress badBitmaskCheck */
- filter[size++] = (struct sock_filter)BPF_STMT(
- BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr)));
+ filter[size++] = STMT(BPF_LD | BPF_W | BPF_ABS,
+ offsetof(struct seccomp_data, nr));
/* pre-check instruction + load syscall number (4 instructions) */
accept = size + n_nodes + n;
@@ -574,14 +557,12 @@ unsigned int filter_build(struct sock_filter filter[], unsigned n)
/* Insert nodes */
for (i = 0; i < n_nodes; i++) {
if (nodes[i] == EMPTY) {
- filter[size++] =
- (struct sock_filter)JUMPA(accept - size);
+ filter[size++] = JUMPA(accept - size);
} else {
nr = get_syscall(nodes[i]);
offset_left = left_child(i) - i - 1;
offset_right = right_child(i) - i - 1;
- filter[size++] = (struct sock_filter)JGE(
- nr, offset_right, offset_left);
+ filter[size++] = JGE(nr, offset_right, offset_left);
}
}
@@ -595,19 +576,16 @@ unsigned int filter_build(struct sock_filter filter[], unsigned n)
/* If the syscall doesn't have any arguments, then notify */
offset = notify - size - 1;
}
- filter[size++] =
- (struct sock_filter)EQ(nr, offset, accept - size);
+ filter[size++] = EQ(nr, offset, accept - size);
/* The arguments block of the next entry are after the total
* number of the instructions for checking the arguments of the current entry
*/
next_offset += get_n_args_syscall_instr(nr) - 1;
}
/* Seccomp accept and notify instruction */
- filter[size++] = (struct sock_filter)BPF_STMT(BPF_RET | BPF_K,
- SECCOMP_RET_ALLOW);
+ filter[size++] = STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
if (!call_entry_count(nr))
- filter[size++] = (struct sock_filter)BPF_STMT(BPF_RET | BPF_K,
- SECCOMP_RET_USER_NOTIF);
+ filter[size++] = STMT(BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF);
/*
@@ -618,8 +596,8 @@ unsigned int filter_build(struct sock_filter filter[], unsigned n)
for (i = 0; i < n; i++) {
size += insert_args(&filter[size], nr);
if (call_entry_count(nr))
- filter[size++] = (struct sock_filter)BPF_STMT(
- BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF);
+ filter[size++] = STMT(BPF_RET | BPF_K,
+ SECCOMP_RET_USER_NOTIF);
}
debug(" BPF: filter with %i call%s has %i instructions",
diff --git a/cooker/filter.h b/cooker/filter.h
index 5257f69..8efdc47 100644
--- a/cooker/filter.h
+++ b/cooker/filter.h
@@ -29,26 +29,25 @@
#error "Unknown endianness"
#endif
+#define JUMP(...) ((struct sock_filter)BPF_JUMP(__VA_ARGS__))
+#define STMT(...) ((struct sock_filter)BPF_STMT(__VA_ARGS__))
+
#define JGE(nr, right, left) \
- BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, (nr), (right), (left))
-#define JUMPA(jump) BPF_JUMP(BPF_JMP | BPF_JA, (jump), 0, 0)
-#define EQ(x, a1, a2) BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (x), (a1), (a2))
+ JUMP(BPF_JMP | BPF_JGE | BPF_K, (nr), (right), (left))
+#define JUMPA(jump) JUMP(BPF_JMP | BPF_JA, (jump), 0, 0)
+#define EQ(x, a1, a2) JUMP(BPF_JMP | BPF_JEQ | BPF_K, (x), (a1), (a2))
#define NEQ(x, a1, a2) EQ((x), (a2), (a1))
-#define GT(x, a1, a2) BPF_JUMP(BPF_JMP + BPF_JGT + BPF_K, (x), (a1), (a2))
-#define GE(x, a1, a2) BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, (x), (a1), (a2))
+#define GT(x, a1, a2) JUMP(BPF_JMP + BPF_JGT + BPF_K, (x), (a1), (a2))
+#define GE(x, a1, a2) JUMP(BPF_JMP + BPF_JGE + BPF_K, (x), (a1), (a2))
#define LT(x, a1, a2) GE((x), (a2), (a1))
#define LE(x, a1, a2) GT((x), (a2), (a1))
-#define LOAD(x) BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (x))
-#define AND(x) BPF_STMT(BPF_ALU | BPF_AND | BPF_IMM, (x))
+#define LOAD(x) STMT(BPF_LD | BPF_W | BPF_ABS, (x))
+#define AND(x) STMT(BPF_ALU | BPF_AND | BPF_IMM, (x))
#define MAX_FILTER 1024
#define MAX_JUMPS 128
#define EMPTY -1
-#define N_SYSCALL 512
-#define MAX_ENTRIES_SYSCALL 16
-#define MAX_ENTRIES N_SYSCALL * MAX_ENTRIES_SYSCALL
-
enum bpf_type { BPF_U32, BPF_U64 };
union bpf_value {
@@ -59,21 +58,17 @@ union bpf_value {
extern const char *bpf_cmp_str[];
enum bpf_cmp { NO_CHECK = 0, EQ, NE, LE, LT, GE, GT, AND_EQ, AND_NE };
-struct bpf_arg {
+struct bpf_field {
+ int arg;
union bpf_value value;
enum bpf_type type;
enum bpf_cmp cmp;
union bpf_value op2;
};
-struct bpf_entry {
- struct bpf_arg args[6];
-};
-
void filter_notify(long nr);
void filter_needs_deref(void);
-void filter_add_arg(int index, struct bpf_arg arg);
+void filter_add_check(struct bpf_field *field);
void filter_write(const char *path);
-void filter_flush_args();
#endif