>Synopsis: The in-kernel BPF interpreter doesn't support BPF_XOR and
>BPF_MOD
>Category: kernel
>Environment:
System : OpenBSD 7.8
Details : OpenBSD 7.8 (GENERIC.MP) #54: Sun Oct 12 12:58:11 MDT 2025
[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
Architecture: OpenBSD.amd64
Machine : amd64
>Description:
Linux introduced two new BPF instructions - BPF_XOR, doing a
exclusive-or, and BPF_MOD, doing a C-style modulo operation.
NetBSD and FreeBSD have added them as well, as has libpcap's user-mode
interpreter, and libpcap's compiler for filter expressions supports XOR and
modulo operations
>How-To-Repeat:
Inspect sys/net/bpf_filter.c
>Fix:
Here's a patch, based on the NetBSD change; I have not tested it, but
it should work, being a straightforward change. It updates the bpf(4) manual
page to document the new instructions, and also includes a man page change to
note that BIOCLOCK sets the locked flag.
Index: share/man/man4/bpf.4
===================================================================
RCS file: /cvs/src/share/man/man4/bpf.4,v
retrieving revision 1.47
diff -u -r1.47 bpf.4
--- share/man/man4/bpf.4 15 Aug 2024 12:20:20 -0000 1.47
+++ share/man/man4/bpf.4 10 Nov 2025 20:51:14 -0000
@@ -189,6 +189,9 @@
.Dv BIOCGSTATS .
.Pp
.It Dv BIOCLOCK
+Sets the locked flag on the
+.Nm
+descriptor.
This ioctl is designed to prevent the security issues associated
with an open
.Nm
@@ -789,6 +792,12 @@
.Sm on
A <- A / k
.Sm off
+.It Xo Dv BPF_ALU No + BPF_MOD No +
+.Dv BPF_K
+.Xc
+.Sm on
+A <- A % k
+.Sm off
.It Xo Dv BPF_ALU No + BPF_AND No +
.Dv BPF_K
.Xc
@@ -801,6 +810,12 @@
.Sm on
A <- A | k
.Sm off
+.It Xo Dv BPF_ALU No + BPF_XOR No +
+.Dv BPF_K
+.Xc
+.Sm on
+A <- A ^ k
+.Sm off
.It Xo Dv BPF_ALU No + BPF_LSH No +
.Dv BPF_K
.Xc
@@ -837,6 +852,12 @@
.Sm on
A <- A / X
.Sm off
+.It Xo Dv BPF_ALU No + BPF_MOD No +
+.Dv BPF_X
+.Xc
+.Sm on
+A <- A % X
+.Sm off
.It Xo Dv BPF_ALU No + BPF_AND No +
.Dv BPF_X
.Xc
@@ -848,6 +869,12 @@
.Xc
.Sm on
A <- A | X
+.Sm off
+.It Xo Dv BPF_ALU No + BPF_XOR No +
+.Dv BPF_X
+.Xc
+.Sm on
+A <- A ^ X
.Sm off
.It Xo Dv BPF_ALU No + BPF_LSH No +
.Dv BPF_X
Index: sys/net/bpf.h
===================================================================
RCS file: /cvs/src/sys/net/bpf.h,v
retrieving revision 1.74
diff -u -r1.74 bpf.h
--- sys/net/bpf.h 4 Mar 2025 01:01:25 -0000 1.74
+++ sys/net/bpf.h 10 Nov 2025 20:51:20 -0000
@@ -255,6 +255,8 @@
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
+#define BPF_MOD 0x90
+#define BPF_XOR 0xa0
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
Index: sys/net/bpf_filter.c
===================================================================
RCS file: /cvs/src/sys/net/bpf_filter.c,v
retrieving revision 1.35
diff -u -r1.35 bpf_filter.c
--- sys/net/bpf_filter.c 7 Jul 2025 02:28:50 -0000 1.35
+++ sys/net/bpf_filter.c 10 Nov 2025 20:51:20 -0000
@@ -307,6 +307,12 @@
A /= X;
continue;
+ case BPF_ALU|BPF_MOD|BPF_X:
+ if (X == 0)
+ return 0;
+ A %= X;
+ continue;
+
case BPF_ALU|BPF_AND|BPF_X:
A &= X;
continue;
@@ -315,6 +321,10 @@
A |= X;
continue;
+ case BPF_ALU|BPF_XOR|BPF_X:
+ A ^= X;
+ continue;
+
case BPF_ALU|BPF_LSH|BPF_X:
A <<= X;
continue;
@@ -339,6 +349,10 @@
A /= pc->k;
continue;
+ case BPF_ALU|BPF_MOD|BPF_K:
+ A %= pc->k;
+ continue;
+
case BPF_ALU|BPF_AND|BPF_K:
A &= pc->k;
continue;
@@ -347,6 +361,10 @@
A |= pc->k;
continue;
+ case BPF_ALU|BPF_XOR|BPF_K:
+ A ^= pc->k;
+ continue;
+
case BPF_ALU|BPF_LSH|BPF_K:
A <<= pc->k;
continue;
@@ -432,12 +450,14 @@
case BPF_SUB:
case BPF_MUL:
case BPF_OR:
+ case BPF_XOR:
case BPF_AND:
case BPF_LSH:
case BPF_RSH:
case BPF_NEG:
break;
case BPF_DIV:
+ case BPF_MOD:
/*
* Check for constant division by 0.
*/