Download raw body.
reshuffle code in bpf_filter.c so bpf_filter and bpf_validate match up
This is just moving code around to result in the same list of case
statements in the filter and validate function.
Also encode BPF_LDX|BPF_MSH|BPF_B as BPF_LDX|BPF_B|BPF_MSH so it is like
all other BPF_LD instructions with BPF_{B,H,W} as 2nd value.
OK?
--
:wq Claudio
diff --git sys/net/bpf_filter.c sys/net/bpf_filter.c
index f9fb870235c..6bbc956b2f0 100644
--- sys/net/bpf_filter.c
+++ sys/net/bpf_filter.c
@@ -232,18 +232,6 @@ _bpf_lfilter(const struct bpf_insn *pc, u_int pc_len, const struct bpf_ops *ops,
return 0;
continue;
- case BPF_LD|BPF_W|BPF_LEN:
- A = wirelen;
- continue;
-
- case BPF_LDX|BPF_W|BPF_LEN:
- X = wirelen;
- continue;
-
- case BPF_LD|BPF_W|BPF_RND:
- A = arc4random();
- continue;
-
case BPF_LD|BPF_W|BPF_IND:
k = X + pc->k;
A = ops->ldw(pkt, k, &err);
@@ -265,7 +253,7 @@ _bpf_lfilter(const struct bpf_insn *pc, u_int pc_len, const struct bpf_ops *ops,
return 0;
continue;
- case BPF_LDX|BPF_MSH|BPF_B:
+ case BPF_LDX|BPF_B|BPF_MSH:
X = ops->ldb(pkt, pc->k, &err);
if (err != 0)
return 0;
@@ -273,6 +261,18 @@ _bpf_lfilter(const struct bpf_insn *pc, u_int pc_len, const struct bpf_ops *ops,
X <<= 2;
continue;
+ case BPF_LD|BPF_W|BPF_LEN:
+ A = wirelen;
+ continue;
+
+ case BPF_LDX|BPF_W|BPF_LEN:
+ X = wirelen;
+ continue;
+
+ case BPF_LD|BPF_W|BPF_RND:
+ A = arc4random();
+ continue;
+
case BPF_LD|BPF_IMM:
A = pc->k;
continue;
@@ -495,6 +495,11 @@ bpf_validate(struct bpf_insn *f, u_int len)
for (i = 0; i < len; ++i) {
p = &f[i];
switch (p->code) {
+ default:
+ return 0;
+ case BPF_RET|BPF_K:
+ case BPF_RET|BPF_A:
+ break;
/*
* Check that memory operations use valid addresses.
*/
@@ -541,6 +546,36 @@ bpf_validate(struct bpf_insn *f, u_int len)
if (p->k >= BPF_MEMWORDS)
return 0;
break;
+ case BPF_JMP|BPF_JA:
+ case BPF_JMP|BPF_JGT|BPF_K:
+ case BPF_JMP|BPF_JGE|BPF_K:
+ case BPF_JMP|BPF_JEQ|BPF_K:
+ case BPF_JMP|BPF_JSET|BPF_K:
+ case BPF_JMP|BPF_JGT|BPF_X:
+ case BPF_JMP|BPF_JGE|BPF_X:
+ case BPF_JMP|BPF_JEQ|BPF_X:
+ case BPF_JMP|BPF_JSET|BPF_X:
+ /*
+ * Check that jumps are forward, and within
+ * the code block.
+ */
+ from = i + 1;
+ switch (BPF_OP(p->code)) {
+ case BPF_JA:
+ if (from + p->k < from || from + p->k >= len)
+ return 0;
+ break;
+ case BPF_JEQ:
+ case BPF_JGT:
+ case BPF_JGE:
+ case BPF_JSET:
+ if (from + p->jt >= len || from + p->jf >= len)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ break;
case BPF_ALU|BPF_ADD|BPF_X:
case BPF_ALU|BPF_SUB|BPF_X:
case BPF_ALU|BPF_MUL|BPF_X:
@@ -591,44 +626,9 @@ bpf_validate(struct bpf_insn *f, u_int len)
return 0;
}
break;
- case BPF_JMP|BPF_JA:
- case BPF_JMP|BPF_JGT|BPF_K:
- case BPF_JMP|BPF_JGE|BPF_K:
- case BPF_JMP|BPF_JEQ|BPF_K:
- case BPF_JMP|BPF_JSET|BPF_K:
- case BPF_JMP|BPF_JGT|BPF_X:
- case BPF_JMP|BPF_JGE|BPF_X:
- case BPF_JMP|BPF_JEQ|BPF_X:
- case BPF_JMP|BPF_JSET|BPF_X:
- /*
- * Check that jumps are forward, and within
- * the code block.
- */
- from = i + 1;
- switch (BPF_OP(p->code)) {
- case BPF_JA:
- if (from + p->k < from || from + p->k >= len)
- return 0;
- break;
- case BPF_JEQ:
- case BPF_JGT:
- case BPF_JGE:
- case BPF_JSET:
- if (from + p->jt >= len || from + p->jf >= len)
- return 0;
- break;
- default:
- return 0;
- }
- break;
- case BPF_RET|BPF_K:
- case BPF_RET|BPF_A:
- break;
case BPF_MISC|BPF_TAX:
case BPF_MISC|BPF_TXA:
break;
- default:
- return 0;
}
}
reshuffle code in bpf_filter.c so bpf_filter and bpf_validate match up