diff options
author | jkim <jkim@FreeBSD.org> | 2008-08-28 22:00:21 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2008-08-28 22:00:21 +0000 |
commit | ced937913865e9e584a26b5ab698a53ac8a2a98c (patch) | |
tree | 3128831df8248fb8a523dc3d10fe8050cc9daa91 /sys | |
parent | f6cff7abd933aa7d4ba342cc5ecbeaa32650bd8b (diff) | |
download | FreeBSD-src-ced937913865e9e584a26b5ab698a53ac8a2a98c.zip FreeBSD-src-ced937913865e9e584a26b5ab698a53ac8a2a98c.tar.gz |
Check invalid BPF codes from bpf_validate(9).
Note that it is not critical because bpf_filter(9) returns zero
when it encounters invalid code at run time.
MFC after: 1 month
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/bpf_filter.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/sys/net/bpf_filter.c b/sys/net/bpf_filter.c index 8c92490..4064317 100644 --- a/sys/net/bpf_filter.c +++ b/sys/net/bpf_filter.c @@ -496,6 +496,25 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) } #ifdef _KERNEL +static u_short bpf_code_map[] = { + 0x10ff, /* 0x00-0x0f: 1111111100001000 */ + 0x3070, /* 0x10-0x1f: 0000111000001100 */ + 0x3131, /* 0x20-0x2f: 1000110010001100 */ + 0x3031, /* 0x30-0x3f: 1000110000001100 */ + 0x3131, /* 0x40-0x4f: 1000110010001100 */ + 0x1011, /* 0x50-0x5f: 1000100000001000 */ + 0x1013, /* 0x60-0x6f: 1100100000001000 */ + 0x1010, /* 0x70-0x7f: 0000100000001000 */ + 0x0093, /* 0x80-0x8f: 1100100100000000 */ + 0x0000, /* 0x90-0x9f: 0000000000000000 */ + 0x0000, /* 0xa0-0xaf: 0000000000000000 */ + 0x0002, /* 0xb0-0xbf: 0100000000000000 */ + 0x0000, /* 0xc0-0xcf: 0000000000000000 */ + 0x0000, /* 0xd0-0xdf: 0000000000000000 */ + 0x0000, /* 0xe0-0xef: 0000000000000000 */ + 0x0000 /* 0xf0-0xff: 0000000000000000 */ +}; + /* * Return true if the 'fcode' is a valid filter program. * The constraints are that each jump be forward and to a valid @@ -521,11 +540,17 @@ bpf_validate(f, len) return 1; for (i = 0; i < len; ++i) { + p = &f[i]; + /* + * Check that the code is valid. + */ + if ((p->code & 0xff00) || + !(bpf_code_map[p->code >> 4] & (1 << (p->code & 0xf)))) + return 0; /* * Check that that jumps are forward, and within * the code block. */ - p = &f[i]; if (BPF_CLASS(p->code) == BPF_JMP) { register int from = i + 1; |