Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
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

Download raw body.

Thread
  • Claudio Jeker:

    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;
 		}
 
 	}