From: Claudio Jeker Subject: reshuffle code in bpf_filter.c so bpf_filter and bpf_validate match up To: tech@openbsd.org Date: Tue, 8 Sep 2026 11:26:55 +0200 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; } }