From 72e5b4d25146e4f1953c050beff292b051f1ab01 Mon Sep 17 00:00:00 2001 From: jkim Date: Tue, 26 Aug 2008 19:24:58 +0000 Subject: Add more test cases for invalid instructions and add comments about bpf_validate(9) issues. --- tools/regression/bpf/bpf_filter/Makefile | 11 ++-- tools/regression/bpf/bpf_filter/bpf_test.c | 83 ++++++++++++++++++++++-- tools/regression/bpf/bpf_filter/tests/test0001.h | 1 + tools/regression/bpf/bpf_filter/tests/test0075.h | 36 ++++++++++ tools/regression/bpf/bpf_filter/tests/test0076.h | 37 +++++++++++ tools/regression/bpf/bpf_filter/tests/test0077.h | 36 ++++++++++ tools/regression/bpf/bpf_filter/tests/test0078.h | 37 +++++++++++ 7 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 tools/regression/bpf/bpf_filter/tests/test0075.h create mode 100644 tools/regression/bpf/bpf_filter/tests/test0076.h create mode 100644 tools/regression/bpf/bpf_filter/tests/test0077.h create mode 100644 tools/regression/bpf/bpf_filter/tests/test0078.h 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 -- cgit v1.1