Module Name: src Committed By: alnsn Date: Wed Feb 11 12:03:30 UTC 2015
Modified Files: src/sys/net: bpf_filter.c Log Message: It's not enough to check that a class of the last instruction is BPF_RET. The opcodes in bpf_validate() must match opcodes understood by bpf_filter(). Found by afl-fuzz http://lcamtuf.coredump.cx/afl/. To generate a diff of this commit: cvs rdiff -u -r1.68 -r1.69 src/sys/net/bpf_filter.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/bpf_filter.c diff -u src/sys/net/bpf_filter.c:1.68 src/sys/net/bpf_filter.c:1.69 --- src/sys/net/bpf_filter.c:1.68 Wed Nov 19 19:35:21 2014 +++ src/sys/net/bpf_filter.c Wed Feb 11 12:03:30 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf_filter.c,v 1.68 2014/11/19 19:35:21 christos Exp $ */ +/* $NetBSD: bpf_filter.c,v 1.69 2015/02/11 12:03:30 alnsn Exp $ */ /*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.68 2014/11/19 19:35:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.69 2015/02/11 12:03:30 alnsn Exp $"); #if 0 #if !(defined(lint) || defined(KERNEL)) @@ -628,8 +628,10 @@ bpf_validate(const struct bpf_insn *f, i if (len > BPF_MAXINSNS) return 0; #endif - if (BPF_CLASS(f[len - 1].code) != BPF_RET) + if (f[len - 1].code != BPF_RET|BPF_K && + f[len - 1].code != BPF_RET|BPF_A) { return 0; + } #if defined(KERNEL) || defined(_KERNEL) /* Note: only the pre-initialised is valid on startup */