Fix BPF instruction count bug.
We were accidentally capping the total number of BPF instructions at
256 when doing label fixup.
Also add a simple binary to print a compiled policy.
Bug: 31848734
Test: Policy attached to the bug works.
Change-Id: I9df058e2f4888289db0219d65ca97851fac515d0
diff --git a/bpf.c b/bpf.c
index 20f2ed0..f56bc11 100644
--- a/bpf.c
+++ b/bpf.c
@@ -172,8 +172,8 @@
printf("len == %d\n", len);
printf("filter:\n");
for (i = 0; i < len; i++) {
- printf("%d: \t{ code=%#x, jt=%u, jf=%u, k=%#x \t}\n",
- i, filter[i].code, filter[i].jt, filter[i].jf, filter[i].k);
+ printf("%d: \t{ code=%#x, jt=%u, jf=%u, k=%#x \t}\n", i,
+ filter[i].code, filter[i].jt, filter[i].jf, filter[i].k);
}
}
@@ -184,41 +184,48 @@
dump_bpf_filter(filter, len);
}
-int bpf_resolve_jumps(struct bpf_labels *labels,
- struct sock_filter *filter, size_t count)
+int bpf_resolve_jumps(struct bpf_labels *labels, struct sock_filter *filter,
+ size_t len)
{
+ size_t insn;
struct sock_filter *begin = filter;
- __u8 insn = count - 1;
- if (count < 1)
+ /* This needs at least two instructions: one jump and one label. */
+ if (len < 2)
return -1;
+
+ if (len > BPF_MAXINSNS)
+ return -1;
+
+ insn = len - 1;
+
/*
* Walk it once, backwards, to build the label table and do fixups.
* Since backward jumps are disallowed by BPF, this is easy.
*/
for (filter += insn; filter >= begin; --insn, --filter) {
- if (filter->code != (BPF_JMP+BPF_JA))
+ if (filter->code != (BPF_JMP + BPF_JA))
continue;
- switch ((filter->jt<<8)|filter->jf) {
- case (JUMP_JT<<8)|JUMP_JF:
+ switch ((filter->jt << 8) | filter->jf) {
+ case (JUMP_JT << 8) | JUMP_JF:
if (labels->labels[filter->k].location == 0xffffffff) {
fprintf(stderr, "Unresolved label: '%s'\n",
labels->labels[filter->k].label);
return 1;
}
- filter->k = labels->labels[filter->k].location -
- (insn + 1);
+ filter->k =
+ labels->labels[filter->k].location - (insn + 1);
filter->jt = 0;
filter->jf = 0;
continue;
- case (LABEL_JT<<8)|LABEL_JF:
+ case (LABEL_JT << 8) | LABEL_JF:
if (labels->labels[filter->k].location != 0xffffffff) {
fprintf(stderr, "Duplicate label use: '%s'\n",
labels->labels[filter->k].label);
return 1;
}
labels->labels[filter->k].location = insn;
- filter->k = 0; /* fall through */
+ filter->k = 0; /* Fall through. */
filter->jt = 0;
filter->jf = 0;
continue;
@@ -246,6 +253,11 @@
if (!strcmp(label, begin->label))
return id;
}
+
+ /* The label wasn't found. Insert it only if there's space. */
+ if (labels->count == BPF_LABELS_MAX) {
+ return -1;
+ }
begin->label = strndup(label, MAX_BPF_LABEL_LEN);
if (!begin->label) {
return -1;