summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2008-08-26 19:24:58 +0000
committerjkim <jkim@FreeBSD.org>2008-08-26 19:24:58 +0000
commit72e5b4d25146e4f1953c050beff292b051f1ab01 (patch)
tree0993c3b8e32abae8a1754c63fabd512340f209b7
parent0044067c33fc86e104f5955264dbbb10085c09ee (diff)
downloadFreeBSD-src-72e5b4d25146e4f1953c050beff292b051f1ab01.zip
FreeBSD-src-72e5b4d25146e4f1953c050beff292b051f1ab01.tar.gz
Add more test cases for invalid instructions and add comments
about bpf_validate(9) issues.
-rw-r--r--tools/regression/bpf/bpf_filter/Makefile11
-rw-r--r--tools/regression/bpf/bpf_filter/bpf_test.c83
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0001.h1
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0075.h36
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0076.h37
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0077.h36
-rw-r--r--tools/regression/bpf/bpf_filter/tests/test0078.h37
7 files changed, 232 insertions, 9 deletions
diff --git a/tools/regression/bpf/bpf_filter/Makefile b/tools/regression/bpf/bpf_filter/Makefile
index a777e70..6b4c1bc 100644
--- a/tools/regression/bpf/bpf_filter/Makefile
+++ b/tools/regression/bpf/bpf_filter/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-TEST_CASES= test0001 test0002 test0003 test0004 \
+TEST_CASES?= test0001 test0002 test0003 test0004 \
test0005 test0006 test0007 test0008 \
test0009 test0010 test0011 test0012 \
test0013 test0014 test0015 test0016 \
@@ -18,9 +18,8 @@ TEST_CASES= test0001 test0002 test0003 test0004 \
test0061 test0062 test0063 test0064 \
test0065 test0066 test0067 test0068 \
test0069 test0070 test0071 test0072 \
- test0073 test0074
-
-WARNS?= 6
+ test0073 test0074 test0075 test0076 \
+ test0077 test0078
SYSDIR?= ${.CURDIR}/../../../../sys
@@ -35,15 +34,17 @@ CFLAGS+= -DLOG_LEVEL="${LOG_LEVEL}"
.endif
.if defined(BPF_VALIDATE)
-CFLAGS+= -DBPF_VALIDATE
+CFLAGS+= -DBPF_VALIDATE=${BPF_VALIDATE}
.endif
.if (${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386") && defined(BPF_JIT)
SRCS+= ${SYSDIR}/net/bpf_jitter.c \
${SYSDIR}/${MACHINE_ARCH}/${MACHINE_ARCH}/bpf_jit_machdep.c
CFLAGS+= -DBPF_JIT_COMPILER
+WARNS?= 6
.else
SRCS+= ${SYSDIR}/net/bpf_filter.c
+WARNS?= 2
.endif
.for TEST in ${TEST_CASES}
diff --git a/tools/regression/bpf/bpf_filter/bpf_test.c b/tools/regression/bpf/bpf_filter/bpf_test.c
index d8b46ef..94e7d7d 100644
--- a/tools/regression/bpf/bpf_filter/bpf_test.c
+++ b/tools/regression/bpf/bpf_filter/bpf_test.c
@@ -89,6 +89,10 @@ bpf_compile_and_filter(void)
return (ret);
}
+#else
+
+u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
+
#endif
#ifdef BPF_VALIDATE
@@ -122,6 +126,61 @@ bpf_validate(const struct bpf_insn *f, int len)
* the code block.
*/
p = &f[i];
+#if BPF_VALIDATE > 1
+ /*
+ * XXX JK: Illegal instructions must be checked here.
+ */
+ switch (p->code) {
+ default:
+ return (0);
+ case BPF_RET|BPF_K:
+ case BPF_RET|BPF_A:
+ case BPF_LD|BPF_W|BPF_ABS:
+ case BPF_LD|BPF_H|BPF_ABS:
+ case BPF_LD|BPF_B|BPF_ABS:
+ case BPF_LD|BPF_W|BPF_LEN:
+ case BPF_LDX|BPF_W|BPF_LEN:
+ case BPF_LD|BPF_W|BPF_IND:
+ case BPF_LD|BPF_H|BPF_IND:
+ case BPF_LD|BPF_B|BPF_IND:
+ case BPF_LDX|BPF_MSH|BPF_B:
+ case BPF_LD|BPF_IMM:
+ case BPF_LDX|BPF_IMM:
+ case BPF_LD|BPF_MEM:
+ case BPF_LDX|BPF_MEM:
+ case BPF_ST:
+ case BPF_STX:
+ 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:
+ case BPF_ALU|BPF_ADD|BPF_X:
+ case BPF_ALU|BPF_SUB|BPF_X:
+ case BPF_ALU|BPF_MUL|BPF_X:
+ case BPF_ALU|BPF_DIV|BPF_X:
+ case BPF_ALU|BPF_AND|BPF_X:
+ case BPF_ALU|BPF_OR|BPF_X:
+ case BPF_ALU|BPF_LSH|BPF_X:
+ case BPF_ALU|BPF_RSH|BPF_X:
+ case BPF_ALU|BPF_ADD|BPF_K:
+ case BPF_ALU|BPF_SUB|BPF_K:
+ case BPF_ALU|BPF_MUL|BPF_K:
+ case BPF_ALU|BPF_DIV|BPF_K:
+ case BPF_ALU|BPF_AND|BPF_K:
+ case BPF_ALU|BPF_OR|BPF_K:
+ case BPF_ALU|BPF_LSH|BPF_K:
+ case BPF_ALU|BPF_RSH|BPF_K:
+ case BPF_ALU|BPF_NEG:
+ case BPF_MISC|BPF_TAX:
+ case BPF_MISC|BPF_TXA:
+ break;
+ }
+#endif
if (BPF_CLASS(p->code) == BPF_JMP) {
register int from = i + 1;
@@ -137,10 +196,20 @@ bpf_validate(const struct bpf_insn *f, int len)
* Check that memory operations use valid addresses.
*/
if ((BPF_CLASS(p->code) == BPF_ST ||
- (BPF_CLASS(p->code) == BPF_LD &&
- (p->code & 0xe0) == BPF_MEM)) &&
+ (BPF_CLASS(p->code) == BPF_LD &&
+ (p->code & 0xe0) == BPF_MEM)) &&
p->k >= BPF_MEMWORDS)
return (0);
+#if BPF_VALIDATE > 1
+ /*
+ * XXX JK: BPF_STX and BPF_LDX|BPF_MEM must be checked.
+ */
+ if ((BPF_CLASS(p->code) == BPF_STX ||
+ (BPF_CLASS(p->code) == BPF_LDX &&
+ (p->code & 0xe0) == BPF_MEM)) &&
+ p->k >= BPF_MEMWORDS)
+ return (0);
+#endif
/*
* Check for constant division by 0.
*/
@@ -171,16 +240,22 @@ main(void)
valid = bpf_validate(pc, nins);
if (valid != 0 && invalid != 0) {
if (verbose > 1)
- printf("Validated invalid instructions:\t");
+ printf("Validated invalid instruction(s):\t");
if (verbose > 0)
printf("FAILED\n");
return (FAILED);
} else if (valid == 0 && invalid == 0) {
if (verbose > 1)
- printf("Invalidated valid instructions:\t");
+ printf("Invalidated valid instruction(s):\t");
if (verbose > 0)
printf("FAILED\n");
return (FAILED);
+ } else if (invalid != 0) {
+ if (verbose > 1)
+ printf("Expected and invalidated:\t");
+ if (verbose > 0)
+ printf("PASSED\n");
+ return (PASSED);
}
#endif
diff --git a/tools/regression/bpf/bpf_filter/tests/test0001.h b/tools/regression/bpf/bpf_filter/tests/test0001.h
index 57c9a95..6016e30 100644
--- a/tools/regression/bpf/bpf_filter/tests/test0001.h
+++ b/tools/regression/bpf/bpf_filter/tests/test0001.h
@@ -7,6 +7,7 @@
/* BPF program */
struct bpf_insn pc[] = {
BPF_STMT(0xdead, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0),
};
/* Packet */
diff --git a/tools/regression/bpf/bpf_filter/tests/test0075.h b/tools/regression/bpf/bpf_filter/tests/test0075.h
new file mode 100644
index 0000000..5c0d1f5
--- /dev/null
+++ b/tools/regression/bpf/bpf_filter/tests/test0075.h
@@ -0,0 +1,36 @@
+/*-
+ * Test 0075: Check boundary conditions (BPF_LD|BPF_MEM)
+ *
+ * $FreeBSD$
+ */
+
+/* BPF program */
+struct bpf_insn pc[] = {
+ BPF_STMT(BPF_LD|BPF_IMM, 0xdeadc0de),
+ BPF_STMT(BPF_LD|BPF_MEM, 0xffffffff),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+/* Packet */
+u_char pkt[] = {
+ 0x00,
+};
+
+/* Packet length seen on wire */
+u_int wirelen = sizeof(pkt);
+
+/* Packet length passed on buffer */
+u_int buflen = sizeof(pkt);
+
+/* Invalid instruction */
+int invalid = 1;
+
+/* Expected return value */
+u_int expect = 0xdeadc0de;
+
+/* Expeced signal */
+#ifdef BPF_JIT_COMPILER
+int expect_signal = SIGSEGV;
+#else
+int expect_signal = SIGBUS;
+#endif
diff --git a/tools/regression/bpf/bpf_filter/tests/test0076.h b/tools/regression/bpf/bpf_filter/tests/test0076.h
new file mode 100644
index 0000000..19dec0d
--- /dev/null
+++ b/tools/regression/bpf/bpf_filter/tests/test0076.h
@@ -0,0 +1,37 @@
+/*-
+ * Test 0076: Check boundary conditions (BPF_LDX|BPF_MEM)
+ *
+ * $FreeBSD$
+ */
+
+/* BPF program */
+struct bpf_insn pc[] = {
+ BPF_STMT(BPF_LD|BPF_IMM, 0xdeadc0de),
+ BPF_STMT(BPF_LDX|BPF_MEM, 0xffffffff),
+ BPF_STMT(BPF_MISC|BPF_TXA, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+/* Packet */
+u_char pkt[] = {
+ 0x00,
+};
+
+/* Packet length seen on wire */
+u_int wirelen = sizeof(pkt);
+
+/* Packet length passed on buffer */
+u_int buflen = sizeof(pkt);
+
+/* Invalid instruction */
+int invalid = 1;
+
+/* Expected return value */
+u_int expect = 0xdeadc0de;
+
+/* Expeced signal */
+#ifdef BPF_JIT_COMPILER
+int expect_signal = SIGSEGV;
+#else
+int expect_signal = SIGBUS;
+#endif
diff --git a/tools/regression/bpf/bpf_filter/tests/test0077.h b/tools/regression/bpf/bpf_filter/tests/test0077.h
new file mode 100644
index 0000000..c4224c1
--- /dev/null
+++ b/tools/regression/bpf/bpf_filter/tests/test0077.h
@@ -0,0 +1,36 @@
+/*-
+ * Test 0077: Check boundary conditions (BPF_ST)
+ *
+ * $FreeBSD$
+ */
+
+/* BPF program */
+struct bpf_insn pc[] = {
+ BPF_STMT(BPF_LD|BPF_IMM, 0xdeadc0de),
+ BPF_STMT(BPF_ST, 0xffffffff),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+/* Packet */
+u_char pkt[] = {
+ 0x00,
+};
+
+/* Packet length seen on wire */
+u_int wirelen = sizeof(pkt);
+
+/* Packet length passed on buffer */
+u_int buflen = sizeof(pkt);
+
+/* Invalid instruction */
+int invalid = 1;
+
+/* Expected return value */
+u_int expect = 0xdeadc0de;
+
+/* Expeced signal */
+#ifdef BPF_JIT_COMPILER
+int expect_signal = SIGSEGV;
+#else
+int expect_signal = SIGBUS;
+#endif
diff --git a/tools/regression/bpf/bpf_filter/tests/test0078.h b/tools/regression/bpf/bpf_filter/tests/test0078.h
new file mode 100644
index 0000000..bd7ee8f
--- /dev/null
+++ b/tools/regression/bpf/bpf_filter/tests/test0078.h
@@ -0,0 +1,37 @@
+/*-
+ * Test 0078: Check boundary conditions (BPF_STX)
+ *
+ * $FreeBSD$
+ */
+
+/* BPF program */
+struct bpf_insn pc[] = {
+ BPF_STMT(BPF_LD|BPF_IMM, 0xdeadc0de),
+ BPF_STMT(BPF_STX, 0xffffffff),
+ BPF_STMT(BPF_MISC|BPF_TXA, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+/* Packet */
+u_char pkt[] = {
+ 0x00,
+};
+
+/* Packet length seen on wire */
+u_int wirelen = sizeof(pkt);
+
+/* Packet length passed on buffer */
+u_int buflen = sizeof(pkt);
+
+/* Invalid instruction */
+int invalid = 1;
+
+/* Expected return value */
+u_int expect = 0xdeadc0de;
+
+/* Expeced signal */
+#ifdef BPF_JIT_COMPILER
+int expect_signal = SIGSEGV;
+#else
+int expect_signal = SIGBUS;
+#endif
OpenPOWER on IntegriCloud