GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libpcap/../../sys/net/bpf_filter.c Lines: 0 133 0.0 %
Date: 2017-11-07 Branches: 0 86 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: bpf_filter.c,v 1.33 2017/09/08 05:36:53 deraadt Exp $	*/
2
/*	$NetBSD: bpf_filter.c,v 1.12 1996/02/13 22:00:00 christos Exp $	*/
3
4
/*
5
 * Copyright (c) 1990, 1991, 1992, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * This code is derived from the Stanford/CMU enet packet filter,
9
 * (net/enet.c) distributed as part of 4.3BSD, and code contributed
10
 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
11
 * Berkeley Laboratory.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions
15
 * are met:
16
 * 1. Redistributions of source code must retain the above copyright
17
 *    notice, this list of conditions and the following disclaimer.
18
 * 2. Redistributions in binary form must reproduce the above copyright
19
 *    notice, this list of conditions and the following disclaimer in the
20
 *    documentation and/or other materials provided with the distribution.
21
 * 3. Neither the name of the University nor the names of its contributors
22
 *    may be used to endorse or promote products derived from this software
23
 *    without specific prior written permission.
24
 *
25
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
 * SUCH DAMAGE.
36
 *
37
 *	@(#)bpf_filter.c	8.1 (Berkeley) 6/10/93
38
 */
39
40
#include <sys/param.h>
41
#include <sys/time.h>
42
#ifndef _KERNEL
43
#include <stdlib.h>
44
#include <string.h>
45
#include "pcap.h"
46
#else
47
#include <sys/systm.h>
48
#endif
49
50
#include <sys/endian.h>
51
52
#ifdef _KERNEL
53
extern int bpf_maxbufsize;
54
#define Static
55
#else /* _KERNEL */
56
#define Static static
57
#endif /* _KERNEL */
58
59
#include <net/bpf.h>
60
61
struct bpf_mem {
62
	const u_char	*pkt;
63
	u_int		 len;
64
};
65
66
Static u_int32_t	bpf_mem_ldw(const void *, u_int32_t, int *);
67
Static u_int32_t	bpf_mem_ldh(const void *, u_int32_t, int *);
68
Static u_int32_t	bpf_mem_ldb(const void *, u_int32_t, int *);
69
70
static const struct bpf_ops bpf_mem_ops = {
71
	bpf_mem_ldw,
72
	bpf_mem_ldh,
73
	bpf_mem_ldb,
74
};
75
76
Static u_int32_t
77
bpf_mem_ldw(const void *mem, u_int32_t k, int *err)
78
{
79
	const struct bpf_mem *bm = mem;
80
	u_int32_t v;
81
82
	*err = 1;
83
84
	if (k + sizeof(v) > bm->len)
85
		return (0);
86
87
	memcpy(&v, bm->pkt + k, sizeof(v));
88
89
	*err = 0;
90
	return ntohl(v);
91
}
92
93
Static u_int32_t
94
bpf_mem_ldh(const void *mem, u_int32_t k, int *err)
95
{
96
	const struct bpf_mem *bm = mem;
97
	u_int16_t v;
98
99
	*err = 1;
100
101
	if (k + sizeof(v) > bm->len)
102
		return (0);
103
104
	memcpy(&v, bm->pkt + k, sizeof(v));
105
106
	*err = 0;
107
	return ntohs(v);
108
}
109
110
Static u_int32_t
111
bpf_mem_ldb(const void *mem, u_int32_t k, int *err)
112
{
113
	const struct bpf_mem *bm = mem;
114
115
	*err = 1;
116
117
	if (k >= bm->len)
118
		return (0);
119
120
	*err = 0;
121
	return bm->pkt[k];
122
}
123
124
/*
125
 * Execute the filter program starting at pc on the packet p
126
 * wirelen is the length of the original packet
127
 * buflen is the amount of data present
128
 */
129
u_int
130
bpf_filter(const struct bpf_insn *pc, const u_char *pkt,
131
    u_int wirelen, u_int buflen)
132
{
133
	struct bpf_mem bm;
134
135
	bm.pkt = pkt;
136
	bm.len = buflen;
137
138
	return _bpf_filter(pc, &bpf_mem_ops, &bm, wirelen);
139
}
140
141
u_int
142
_bpf_filter(const struct bpf_insn *pc, const struct bpf_ops *ops,
143
    const void *pkt, u_int wirelen)
144
{
145
	u_int32_t A = 0, X = 0;
146
	u_int32_t k;
147
	int32_t mem[BPF_MEMWORDS];
148
	int err;
149
150
	if (pc == NULL) {
151
		/*
152
		 * No filter means accept all.
153
		 */
154
		return (u_int)-1;
155
	}
156
157
	memset(mem, 0, sizeof(mem));
158
159
	--pc;
160
	while (1) {
161
		++pc;
162
		switch (pc->code) {
163
164
		default:
165
#ifdef _KERNEL
166
			return 0;
167
#else
168
			abort();
169
#endif
170
		case BPF_RET|BPF_K:
171
			return (u_int)pc->k;
172
173
		case BPF_RET|BPF_A:
174
			return (u_int)A;
175
176
		case BPF_LD|BPF_W|BPF_ABS:
177
			A = ops->ldw(pkt, pc->k, &err);
178
			if (err != 0)
179
				return 0;
180
			continue;
181
182
		case BPF_LD|BPF_H|BPF_ABS:
183
			A = ops->ldh(pkt, pc->k, &err);
184
			if (err != 0)
185
				return 0;
186
			continue;
187
188
		case BPF_LD|BPF_B|BPF_ABS:
189
			A = ops->ldb(pkt, pc->k, &err);
190
			if (err != 0)
191
				return 0;
192
			continue;
193
194
		case BPF_LD|BPF_W|BPF_LEN:
195
			A = wirelen;
196
			continue;
197
198
		case BPF_LDX|BPF_W|BPF_LEN:
199
			X = wirelen;
200
			continue;
201
202
		case BPF_LD|BPF_W|BPF_IND:
203
			k = X + pc->k;
204
			A = ops->ldw(pkt, k, &err);
205
			if (err != 0)
206
				return 0;
207
			continue;
208
209
		case BPF_LD|BPF_H|BPF_IND:
210
			k = X + pc->k;
211
			A = ops->ldh(pkt, k, &err);
212
			if (err != 0)
213
				return 0;
214
			continue;
215
216
		case BPF_LD|BPF_B|BPF_IND:
217
			k = X + pc->k;
218
			A = ops->ldb(pkt, k, &err);
219
			if (err != 0)
220
				return 0;
221
			continue;
222
223
		case BPF_LDX|BPF_MSH|BPF_B:
224
			X = ops->ldb(pkt, pc->k, &err);
225
			if (err != 0)
226
				return 0;
227
			X &= 0xf;
228
			X <<= 2;
229
			continue;
230
231
		case BPF_LD|BPF_IMM:
232
			A = pc->k;
233
			continue;
234
235
		case BPF_LDX|BPF_IMM:
236
			X = pc->k;
237
			continue;
238
239
		case BPF_LD|BPF_MEM:
240
			A = mem[pc->k];
241
			continue;
242
243
		case BPF_LDX|BPF_MEM:
244
			X = mem[pc->k];
245
			continue;
246
247
		case BPF_ST:
248
			mem[pc->k] = A;
249
			continue;
250
251
		case BPF_STX:
252
			mem[pc->k] = X;
253
			continue;
254
255
		case BPF_JMP|BPF_JA:
256
			pc += pc->k;
257
			continue;
258
259
		case BPF_JMP|BPF_JGT|BPF_K:
260
			pc += (A > pc->k) ? pc->jt : pc->jf;
261
			continue;
262
263
		case BPF_JMP|BPF_JGE|BPF_K:
264
			pc += (A >= pc->k) ? pc->jt : pc->jf;
265
			continue;
266
267
		case BPF_JMP|BPF_JEQ|BPF_K:
268
			pc += (A == pc->k) ? pc->jt : pc->jf;
269
			continue;
270
271
		case BPF_JMP|BPF_JSET|BPF_K:
272
			pc += (A & pc->k) ? pc->jt : pc->jf;
273
			continue;
274
275
		case BPF_JMP|BPF_JGT|BPF_X:
276
			pc += (A > X) ? pc->jt : pc->jf;
277
			continue;
278
279
		case BPF_JMP|BPF_JGE|BPF_X:
280
			pc += (A >= X) ? pc->jt : pc->jf;
281
			continue;
282
283
		case BPF_JMP|BPF_JEQ|BPF_X:
284
			pc += (A == X) ? pc->jt : pc->jf;
285
			continue;
286
287
		case BPF_JMP|BPF_JSET|BPF_X:
288
			pc += (A & X) ? pc->jt : pc->jf;
289
			continue;
290
291
		case BPF_ALU|BPF_ADD|BPF_X:
292
			A += X;
293
			continue;
294
295
		case BPF_ALU|BPF_SUB|BPF_X:
296
			A -= X;
297
			continue;
298
299
		case BPF_ALU|BPF_MUL|BPF_X:
300
			A *= X;
301
			continue;
302
303
		case BPF_ALU|BPF_DIV|BPF_X:
304
			if (X == 0)
305
				return 0;
306
			A /= X;
307
			continue;
308
309
		case BPF_ALU|BPF_AND|BPF_X:
310
			A &= X;
311
			continue;
312
313
		case BPF_ALU|BPF_OR|BPF_X:
314
			A |= X;
315
			continue;
316
317
		case BPF_ALU|BPF_LSH|BPF_X:
318
			A <<= X;
319
			continue;
320
321
		case BPF_ALU|BPF_RSH|BPF_X:
322
			A >>= X;
323
			continue;
324
325
		case BPF_ALU|BPF_ADD|BPF_K:
326
			A += pc->k;
327
			continue;
328
329
		case BPF_ALU|BPF_SUB|BPF_K:
330
			A -= pc->k;
331
			continue;
332
333
		case BPF_ALU|BPF_MUL|BPF_K:
334
			A *= pc->k;
335
			continue;
336
337
		case BPF_ALU|BPF_DIV|BPF_K:
338
			A /= pc->k;
339
			continue;
340
341
		case BPF_ALU|BPF_AND|BPF_K:
342
			A &= pc->k;
343
			continue;
344
345
		case BPF_ALU|BPF_OR|BPF_K:
346
			A |= pc->k;
347
			continue;
348
349
		case BPF_ALU|BPF_LSH|BPF_K:
350
			A <<= pc->k;
351
			continue;
352
353
		case BPF_ALU|BPF_RSH|BPF_K:
354
			A >>= pc->k;
355
			continue;
356
357
		case BPF_ALU|BPF_NEG:
358
			A = -A;
359
			continue;
360
361
		case BPF_MISC|BPF_TAX:
362
			X = A;
363
			continue;
364
365
		case BPF_MISC|BPF_TXA:
366
			A = X;
367
			continue;
368
		}
369
	}
370
}
371
372
#ifdef _KERNEL
373
/*
374
 * Return true if the 'fcode' is a valid filter program.
375
 * The constraints are that each jump be forward and to a valid
376
 * code and memory operations use valid addresses.  The code
377
 * must terminate with either an accept or reject.
378
 *
379
 * The kernel needs to be able to verify an application's filter code.
380
 * Otherwise, a bogus program could easily crash the system.
381
 */
382
int
383
bpf_validate(struct bpf_insn *f, int len)
384
{
385
	u_int i, from;
386
	struct bpf_insn *p;
387
388
	if (len < 1 || len > BPF_MAXINSNS)
389
		return 0;
390
391
	for (i = 0; i < len; ++i) {
392
		p = &f[i];
393
		switch (BPF_CLASS(p->code)) {
394
		/*
395
		 * Check that memory operations use valid addresses.
396
		 */
397
		case BPF_LD:
398
		case BPF_LDX:
399
			switch (BPF_MODE(p->code)) {
400
			case BPF_IMM:
401
				break;
402
			case BPF_ABS:
403
			case BPF_IND:
404
			case BPF_MSH:
405
				/*
406
				 * More strict check with actual packet length
407
				 * is done runtime.
408
				 */
409
				if (p->k >= bpf_maxbufsize)
410
					return 0;
411
				break;
412
			case BPF_MEM:
413
				if (p->k >= BPF_MEMWORDS)
414
					return 0;
415
				break;
416
			case BPF_LEN:
417
				break;
418
			default:
419
				return 0;
420
			}
421
			break;
422
		case BPF_ST:
423
		case BPF_STX:
424
			if (p->k >= BPF_MEMWORDS)
425
				return 0;
426
			break;
427
		case BPF_ALU:
428
			switch (BPF_OP(p->code)) {
429
			case BPF_ADD:
430
			case BPF_SUB:
431
			case BPF_MUL:
432
			case BPF_OR:
433
			case BPF_AND:
434
			case BPF_LSH:
435
			case BPF_RSH:
436
			case BPF_NEG:
437
				break;
438
			case BPF_DIV:
439
				/*
440
				 * Check for constant division by 0.
441
				 */
442
				if (BPF_SRC(p->code) == BPF_K && p->k == 0)
443
					return 0;
444
				break;
445
			default:
446
				return 0;
447
			}
448
			break;
449
		case BPF_JMP:
450
			/*
451
			 * Check that jumps are forward, and within
452
			 * the code block.
453
			 */
454
			from = i + 1;
455
			switch (BPF_OP(p->code)) {
456
			case BPF_JA:
457
				if (from + p->k < from || from + p->k >= len)
458
					return 0;
459
				break;
460
			case BPF_JEQ:
461
			case BPF_JGT:
462
			case BPF_JGE:
463
			case BPF_JSET:
464
				if (from + p->jt >= len || from + p->jf >= len)
465
					return 0;
466
				break;
467
			default:
468
				return 0;
469
			}
470
			break;
471
		case BPF_RET:
472
			break;
473
		case BPF_MISC:
474
			break;
475
		default:
476
			return 0;
477
		}
478
479
	}
480
	return BPF_CLASS(f[len - 1].code) == BPF_RET;
481
}
482
#endif