1 1.73 christos /* $NetBSD: bpf_filter.c,v 1.73 2024/09/02 15:34:08 christos Exp $ */ 2 1.6 cgd 3 1.14 christos /*- 4 1.14 christos * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 1.5 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from the Stanford/CMU enet packet filter, 8 1.1 cgd * (net/enet.c) distributed as part of 4.3BSD, and code contributed 9 1.5 mycroft * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 10 1.2 cgd * Berkeley Laboratory. 11 1.1 cgd * 12 1.1 cgd * Redistribution and use in source and binary forms, with or without 13 1.1 cgd * modification, are permitted provided that the following conditions 14 1.1 cgd * are met: 15 1.1 cgd * 1. Redistributions of source code must retain the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer. 17 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 cgd * notice, this list of conditions and the following disclaimer in the 19 1.1 cgd * documentation and/or other materials provided with the distribution. 20 1.20 agc * 3. Neither the name of the University nor the names of its contributors 21 1.1 cgd * may be used to endorse or promote products derived from this software 22 1.1 cgd * without specific prior written permission. 23 1.1 cgd * 24 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 1.1 cgd * SUCH DAMAGE. 35 1.1 cgd * 36 1.6 cgd * @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93 37 1.1 cgd */ 38 1.18 lukem 39 1.18 lukem #include <sys/cdefs.h> 40 1.73 christos __KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.73 2024/09/02 15:34:08 christos Exp $"); 41 1.1 cgd 42 1.14 christos #if 0 43 1.14 christos #if !(defined(lint) || defined(KERNEL)) 44 1.14 christos static const char rcsid[] = 45 1.14 christos "@(#) Header: bpf_filter.c,v 1.33 97/04/26 13:37:18 leres Exp (LBL)"; 46 1.14 christos #endif 47 1.14 christos #endif 48 1.14 christos 49 1.1 cgd #include <sys/param.h> 50 1.1 cgd #include <sys/time.h> 51 1.44 christos #include <sys/kmem.h> 52 1.33 cbiere #include <sys/endian.h> 53 1.4 mycroft 54 1.71 pgoyette #ifdef _KERNEL 55 1.71 pgoyette #include <sys/module.h> 56 1.71 pgoyette #endif 57 1.71 pgoyette 58 1.61 rmind #define __BPF_PRIVATE 59 1.56 rmind #include <net/bpf.h> 60 1.56 rmind 61 1.56 rmind #ifdef _KERNEL 62 1.56 rmind 63 1.56 rmind bpf_ctx_t * 64 1.56 rmind bpf_create(void) 65 1.56 rmind { 66 1.56 rmind return kmem_zalloc(sizeof(bpf_ctx_t), KM_SLEEP); 67 1.56 rmind } 68 1.56 rmind 69 1.56 rmind void 70 1.56 rmind bpf_destroy(bpf_ctx_t *bc) 71 1.56 rmind { 72 1.56 rmind kmem_free(bc, sizeof(bpf_ctx_t)); 73 1.56 rmind } 74 1.56 rmind 75 1.56 rmind int 76 1.56 rmind bpf_set_cop(bpf_ctx_t *bc, const bpf_copfunc_t *funcs, size_t n) 77 1.56 rmind { 78 1.56 rmind bc->copfuncs = funcs; 79 1.56 rmind bc->nfuncs = n; 80 1.56 rmind return 0; 81 1.56 rmind } 82 1.56 rmind 83 1.62 alnsn int 84 1.62 alnsn bpf_set_extmem(bpf_ctx_t *bc, size_t nwords, bpf_memword_init_t preinited) 85 1.61 rmind { 86 1.65 alnsn if (nwords > BPF_MAX_MEMWORDS || (preinited >> nwords) != 0) { 87 1.64 rmind return EINVAL; 88 1.64 rmind } 89 1.62 alnsn bc->extwords = nwords; 90 1.63 rmind bc->preinited = preinited; 91 1.62 alnsn return 0; 92 1.61 rmind } 93 1.61 rmind 94 1.56 rmind #endif 95 1.56 rmind 96 1.33 cbiere #define EXTRACT_SHORT(p) be16dec(p) 97 1.33 cbiere #define EXTRACT_LONG(p) be32dec(p) 98 1.1 cgd 99 1.9 jtc #ifdef _KERNEL 100 1.1 cgd #include <sys/mbuf.h> 101 1.22 rpaulo #define MINDEX(len, m, k) \ 102 1.51 rmind { \ 103 1.22 rpaulo len = m->m_len; \ 104 1.22 rpaulo while (k >= len) { \ 105 1.22 rpaulo k -= len; \ 106 1.22 rpaulo m = m->m_next; \ 107 1.22 rpaulo if (m == 0) \ 108 1.22 rpaulo return 0; \ 109 1.22 rpaulo len = m->m_len; \ 110 1.51 rmind } \ 111 1.1 cgd } 112 1.1 cgd 113 1.62 alnsn uint32_t m_xword(const struct mbuf *, uint32_t, int *); 114 1.62 alnsn uint32_t m_xhalf(const struct mbuf *, uint32_t, int *); 115 1.62 alnsn uint32_t m_xbyte(const struct mbuf *, uint32_t, int *); 116 1.62 alnsn 117 1.62 alnsn #define xword(p, k, err) m_xword((const struct mbuf *)(p), (k), (err)) 118 1.62 alnsn #define xhalf(p, k, err) m_xhalf((const struct mbuf *)(p), (k), (err)) 119 1.62 alnsn #define xbyte(p, k, err) m_xbyte((const struct mbuf *)(p), (k), (err)) 120 1.12 christos 121 1.55 alnsn uint32_t 122 1.37 christos m_xword(const struct mbuf *m, uint32_t k, int *err) 123 1.1 cgd { 124 1.15 augustss int len; 125 1.15 augustss u_char *cp, *np; 126 1.15 augustss struct mbuf *m0; 127 1.1 cgd 128 1.53 alnsn *err = 1; 129 1.10 mycroft MINDEX(len, m, k); 130 1.1 cgd cp = mtod(m, u_char *) + k; 131 1.66 alnsn if (len - k >= 4) { 132 1.1 cgd *err = 0; 133 1.1 cgd return EXTRACT_LONG(cp); 134 1.1 cgd } 135 1.1 cgd m0 = m->m_next; 136 1.66 alnsn if (m0 == 0 || (len - k) + m0->m_len < 4) 137 1.32 oster return 0; 138 1.1 cgd *err = 0; 139 1.1 cgd np = mtod(m0, u_char *); 140 1.51 rmind 141 1.1 cgd switch (len - k) { 142 1.1 cgd case 1: 143 1.10 mycroft return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; 144 1.1 cgd case 2: 145 1.10 mycroft return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; 146 1.1 cgd default: 147 1.10 mycroft return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; 148 1.1 cgd } 149 1.1 cgd } 150 1.1 cgd 151 1.55 alnsn uint32_t 152 1.37 christos m_xhalf(const struct mbuf *m, uint32_t k, int *err) 153 1.1 cgd { 154 1.15 augustss int len; 155 1.15 augustss u_char *cp; 156 1.15 augustss struct mbuf *m0; 157 1.1 cgd 158 1.53 alnsn *err = 1; 159 1.10 mycroft MINDEX(len, m, k); 160 1.1 cgd cp = mtod(m, u_char *) + k; 161 1.66 alnsn if (len - k >= 2) { 162 1.1 cgd *err = 0; 163 1.1 cgd return EXTRACT_SHORT(cp); 164 1.1 cgd } 165 1.1 cgd m0 = m->m_next; 166 1.54 alnsn if (m0 == 0) 167 1.32 oster return 0; 168 1.1 cgd *err = 0; 169 1.10 mycroft return (cp[0] << 8) | mtod(m0, u_char *)[0]; 170 1.1 cgd } 171 1.55 alnsn 172 1.55 alnsn uint32_t 173 1.55 alnsn m_xbyte(const struct mbuf *m, uint32_t k, int *err) 174 1.55 alnsn { 175 1.55 alnsn int len; 176 1.55 alnsn 177 1.66 alnsn *err = 1; 178 1.66 alnsn MINDEX(len, m, k); 179 1.55 alnsn *err = 0; 180 1.55 alnsn return mtod(m, u_char *)[k]; 181 1.55 alnsn } 182 1.17 matt #else /* _KERNEL */ 183 1.17 matt #include <stdlib.h> 184 1.17 matt #endif /* !_KERNEL */ 185 1.8 mycroft 186 1.8 mycroft #include <net/bpf.h> 187 1.1 cgd 188 1.1 cgd /* 189 1.1 cgd * Execute the filter program starting at pc on the packet p 190 1.1 cgd * wirelen is the length of the original packet 191 1.1 cgd * buflen is the amount of data present 192 1.1 cgd */ 193 1.56 rmind #ifdef _KERNEL 194 1.58 rmind 195 1.56 rmind u_int 196 1.58 rmind bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, 197 1.58 rmind u_int buflen) 198 1.58 rmind { 199 1.62 alnsn uint32_t mem[BPF_MEMWORDS]; 200 1.61 rmind bpf_args_t args = { 201 1.62 alnsn .pkt = p, 202 1.61 rmind .wirelen = wirelen, 203 1.61 rmind .buflen = buflen, 204 1.62 alnsn .mem = mem, 205 1.61 rmind .arg = NULL 206 1.61 rmind }; 207 1.62 alnsn 208 1.62 alnsn return bpf_filter_ext(NULL, pc, &args); 209 1.58 rmind } 210 1.58 rmind 211 1.58 rmind u_int 212 1.62 alnsn bpf_filter_ext(const bpf_ctx_t *bc, const struct bpf_insn *pc, bpf_args_t *args) 213 1.56 rmind #else 214 1.73 christos __strong_alias(pcapint_filter, bpf_filter) 215 1.1 cgd u_int 216 1.37 christos bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, 217 1.37 christos u_int buflen) 218 1.56 rmind #endif 219 1.1 cgd { 220 1.24 rpaulo uint32_t A, X, k; 221 1.61 rmind #ifndef _KERNEL 222 1.62 alnsn uint32_t mem[BPF_MEMWORDS]; 223 1.61 rmind bpf_args_t args_store = { 224 1.62 alnsn .pkt = p, 225 1.61 rmind .wirelen = wirelen, 226 1.61 rmind .buflen = buflen, 227 1.62 alnsn .mem = mem, 228 1.61 rmind .arg = NULL 229 1.61 rmind }; 230 1.61 rmind bpf_args_t * const args = &args_store; 231 1.61 rmind #else 232 1.62 alnsn const uint8_t * const p = args->pkt; 233 1.56 rmind #endif 234 1.51 rmind if (pc == 0) { 235 1.1 cgd /* 236 1.1 cgd * No filter means accept all. 237 1.1 cgd */ 238 1.1 cgd return (u_int)-1; 239 1.51 rmind } 240 1.51 rmind 241 1.52 rmind /* 242 1.52 rmind * Note: safe to leave memwords uninitialised, as the validation 243 1.52 rmind * step ensures that it will not be read, if it was not written. 244 1.52 rmind */ 245 1.14 christos A = 0; 246 1.14 christos X = 0; 247 1.1 cgd --pc; 248 1.51 rmind 249 1.46 christos for (;;) { 250 1.1 cgd ++pc; 251 1.1 cgd switch (pc->code) { 252 1.1 cgd 253 1.1 cgd default: 254 1.9 jtc #ifdef _KERNEL 255 1.1 cgd return 0; 256 1.1 cgd #else 257 1.1 cgd abort(); 258 1.46 christos /*NOTREACHED*/ 259 1.21 perry #endif 260 1.1 cgd case BPF_RET|BPF_K: 261 1.1 cgd return (u_int)pc->k; 262 1.1 cgd 263 1.1 cgd case BPF_RET|BPF_A: 264 1.1 cgd return (u_int)A; 265 1.1 cgd 266 1.1 cgd case BPF_LD|BPF_W|BPF_ABS: 267 1.1 cgd k = pc->k; 268 1.61 rmind if (k > args->buflen || 269 1.61 rmind sizeof(int32_t) > args->buflen - k) { 270 1.9 jtc #ifdef _KERNEL 271 1.51 rmind int merr; 272 1.1 cgd 273 1.61 rmind if (args->buflen != 0) 274 1.1 cgd return 0; 275 1.62 alnsn A = xword(args->pkt, k, &merr); 276 1.1 cgd if (merr != 0) 277 1.1 cgd return 0; 278 1.1 cgd continue; 279 1.1 cgd #else 280 1.1 cgd return 0; 281 1.1 cgd #endif 282 1.1 cgd } 283 1.7 mycroft A = EXTRACT_LONG(&p[k]); 284 1.1 cgd continue; 285 1.1 cgd 286 1.1 cgd case BPF_LD|BPF_H|BPF_ABS: 287 1.1 cgd k = pc->k; 288 1.61 rmind if (k > args->buflen || 289 1.61 rmind sizeof(int16_t) > args->buflen - k) { 290 1.9 jtc #ifdef _KERNEL 291 1.1 cgd int merr; 292 1.1 cgd 293 1.61 rmind if (args->buflen != 0) 294 1.1 cgd return 0; 295 1.62 alnsn A = xhalf(args->pkt, k, &merr); 296 1.32 oster if (merr != 0) 297 1.32 oster return 0; 298 1.1 cgd continue; 299 1.1 cgd #else 300 1.1 cgd return 0; 301 1.1 cgd #endif 302 1.1 cgd } 303 1.1 cgd A = EXTRACT_SHORT(&p[k]); 304 1.1 cgd continue; 305 1.1 cgd 306 1.1 cgd case BPF_LD|BPF_B|BPF_ABS: 307 1.1 cgd k = pc->k; 308 1.61 rmind if (k >= args->buflen) { 309 1.9 jtc #ifdef _KERNEL 310 1.60 rmind int merr; 311 1.1 cgd 312 1.61 rmind if (args->buflen != 0) 313 1.1 cgd return 0; 314 1.62 alnsn A = xbyte(args->pkt, k, &merr); 315 1.66 alnsn if (merr != 0) 316 1.66 alnsn return 0; 317 1.1 cgd continue; 318 1.1 cgd #else 319 1.1 cgd return 0; 320 1.1 cgd #endif 321 1.1 cgd } 322 1.1 cgd A = p[k]; 323 1.1 cgd continue; 324 1.1 cgd 325 1.1 cgd case BPF_LD|BPF_W|BPF_LEN: 326 1.61 rmind A = args->wirelen; 327 1.1 cgd continue; 328 1.1 cgd 329 1.1 cgd case BPF_LDX|BPF_W|BPF_LEN: 330 1.61 rmind X = args->wirelen; 331 1.1 cgd continue; 332 1.1 cgd 333 1.1 cgd case BPF_LD|BPF_W|BPF_IND: 334 1.1 cgd k = X + pc->k; 335 1.67 alnsn if (k < X || k >= args->buflen || 336 1.61 rmind sizeof(int32_t) > args->buflen - k) { 337 1.9 jtc #ifdef _KERNEL 338 1.51 rmind int merr; 339 1.1 cgd 340 1.67 alnsn if (k < X || args->buflen != 0) 341 1.1 cgd return 0; 342 1.62 alnsn A = xword(args->pkt, k, &merr); 343 1.1 cgd if (merr != 0) 344 1.1 cgd return 0; 345 1.1 cgd continue; 346 1.1 cgd #else 347 1.1 cgd return 0; 348 1.1 cgd #endif 349 1.1 cgd } 350 1.7 mycroft A = EXTRACT_LONG(&p[k]); 351 1.1 cgd continue; 352 1.1 cgd 353 1.1 cgd case BPF_LD|BPF_H|BPF_IND: 354 1.1 cgd k = X + pc->k; 355 1.67 alnsn if (k < X || k >= args->buflen || 356 1.61 rmind sizeof(int16_t) > args->buflen - k) { 357 1.9 jtc #ifdef _KERNEL 358 1.51 rmind int merr; 359 1.1 cgd 360 1.67 alnsn if (k < X || args->buflen != 0) 361 1.1 cgd return 0; 362 1.62 alnsn A = xhalf(args->pkt, k, &merr); 363 1.1 cgd if (merr != 0) 364 1.1 cgd return 0; 365 1.1 cgd continue; 366 1.1 cgd #else 367 1.1 cgd return 0; 368 1.1 cgd #endif 369 1.1 cgd } 370 1.1 cgd A = EXTRACT_SHORT(&p[k]); 371 1.1 cgd continue; 372 1.1 cgd 373 1.1 cgd case BPF_LD|BPF_B|BPF_IND: 374 1.1 cgd k = X + pc->k; 375 1.67 alnsn if (k < X || k >= args->buflen) { 376 1.9 jtc #ifdef _KERNEL 377 1.60 rmind int merr; 378 1.1 cgd 379 1.67 alnsn if (k < X || args->buflen != 0) 380 1.1 cgd return 0; 381 1.62 alnsn A = xbyte(args->pkt, k, &merr); 382 1.66 alnsn if (merr != 0) 383 1.66 alnsn return 0; 384 1.1 cgd continue; 385 1.1 cgd #else 386 1.1 cgd return 0; 387 1.1 cgd #endif 388 1.1 cgd } 389 1.1 cgd A = p[k]; 390 1.1 cgd continue; 391 1.1 cgd 392 1.1 cgd case BPF_LDX|BPF_MSH|BPF_B: 393 1.1 cgd k = pc->k; 394 1.61 rmind if (k >= args->buflen) { 395 1.9 jtc #ifdef _KERNEL 396 1.60 rmind int merr; 397 1.1 cgd 398 1.61 rmind if (args->buflen != 0) 399 1.1 cgd return 0; 400 1.62 alnsn X = (xbyte(args->pkt, k, &merr) & 0xf) << 2; 401 1.66 alnsn if (merr != 0) 402 1.66 alnsn return 0; 403 1.1 cgd continue; 404 1.1 cgd #else 405 1.1 cgd return 0; 406 1.1 cgd #endif 407 1.1 cgd } 408 1.1 cgd X = (p[pc->k] & 0xf) << 2; 409 1.1 cgd continue; 410 1.1 cgd 411 1.1 cgd case BPF_LD|BPF_IMM: 412 1.1 cgd A = pc->k; 413 1.1 cgd continue; 414 1.1 cgd 415 1.1 cgd case BPF_LDX|BPF_IMM: 416 1.1 cgd X = pc->k; 417 1.1 cgd continue; 418 1.1 cgd 419 1.1 cgd case BPF_LD|BPF_MEM: 420 1.61 rmind A = args->mem[pc->k]; 421 1.1 cgd continue; 422 1.21 perry 423 1.1 cgd case BPF_LDX|BPF_MEM: 424 1.61 rmind X = args->mem[pc->k]; 425 1.1 cgd continue; 426 1.1 cgd 427 1.1 cgd case BPF_ST: 428 1.61 rmind args->mem[pc->k] = A; 429 1.1 cgd continue; 430 1.1 cgd 431 1.1 cgd case BPF_STX: 432 1.61 rmind args->mem[pc->k] = X; 433 1.1 cgd continue; 434 1.1 cgd 435 1.1 cgd case BPF_JMP|BPF_JA: 436 1.1 cgd pc += pc->k; 437 1.1 cgd continue; 438 1.1 cgd 439 1.1 cgd case BPF_JMP|BPF_JGT|BPF_K: 440 1.1 cgd pc += (A > pc->k) ? pc->jt : pc->jf; 441 1.1 cgd continue; 442 1.1 cgd 443 1.1 cgd case BPF_JMP|BPF_JGE|BPF_K: 444 1.1 cgd pc += (A >= pc->k) ? pc->jt : pc->jf; 445 1.1 cgd continue; 446 1.1 cgd 447 1.1 cgd case BPF_JMP|BPF_JEQ|BPF_K: 448 1.1 cgd pc += (A == pc->k) ? pc->jt : pc->jf; 449 1.1 cgd continue; 450 1.1 cgd 451 1.1 cgd case BPF_JMP|BPF_JSET|BPF_K: 452 1.1 cgd pc += (A & pc->k) ? pc->jt : pc->jf; 453 1.1 cgd continue; 454 1.1 cgd 455 1.1 cgd case BPF_JMP|BPF_JGT|BPF_X: 456 1.1 cgd pc += (A > X) ? pc->jt : pc->jf; 457 1.1 cgd continue; 458 1.1 cgd 459 1.1 cgd case BPF_JMP|BPF_JGE|BPF_X: 460 1.1 cgd pc += (A >= X) ? pc->jt : pc->jf; 461 1.1 cgd continue; 462 1.1 cgd 463 1.1 cgd case BPF_JMP|BPF_JEQ|BPF_X: 464 1.1 cgd pc += (A == X) ? pc->jt : pc->jf; 465 1.1 cgd continue; 466 1.1 cgd 467 1.1 cgd case BPF_JMP|BPF_JSET|BPF_X: 468 1.1 cgd pc += (A & X) ? pc->jt : pc->jf; 469 1.1 cgd continue; 470 1.1 cgd 471 1.1 cgd case BPF_ALU|BPF_ADD|BPF_X: 472 1.1 cgd A += X; 473 1.1 cgd continue; 474 1.21 perry 475 1.1 cgd case BPF_ALU|BPF_SUB|BPF_X: 476 1.1 cgd A -= X; 477 1.1 cgd continue; 478 1.21 perry 479 1.1 cgd case BPF_ALU|BPF_MUL|BPF_X: 480 1.1 cgd A *= X; 481 1.1 cgd continue; 482 1.21 perry 483 1.1 cgd case BPF_ALU|BPF_DIV|BPF_X: 484 1.1 cgd if (X == 0) 485 1.1 cgd return 0; 486 1.1 cgd A /= X; 487 1.1 cgd continue; 488 1.21 perry 489 1.68 christos case BPF_ALU|BPF_MOD|BPF_X: 490 1.68 christos if (X == 0) 491 1.68 christos return 0; 492 1.68 christos A %= X; 493 1.68 christos continue; 494 1.68 christos 495 1.1 cgd case BPF_ALU|BPF_AND|BPF_X: 496 1.1 cgd A &= X; 497 1.1 cgd continue; 498 1.21 perry 499 1.1 cgd case BPF_ALU|BPF_OR|BPF_X: 500 1.1 cgd A |= X; 501 1.1 cgd continue; 502 1.1 cgd 503 1.68 christos case BPF_ALU|BPF_XOR|BPF_X: 504 1.68 christos A ^= X; 505 1.68 christos continue; 506 1.68 christos 507 1.1 cgd case BPF_ALU|BPF_LSH|BPF_X: 508 1.1 cgd A <<= X; 509 1.1 cgd continue; 510 1.1 cgd 511 1.1 cgd case BPF_ALU|BPF_RSH|BPF_X: 512 1.1 cgd A >>= X; 513 1.1 cgd continue; 514 1.1 cgd 515 1.1 cgd case BPF_ALU|BPF_ADD|BPF_K: 516 1.1 cgd A += pc->k; 517 1.1 cgd continue; 518 1.21 perry 519 1.1 cgd case BPF_ALU|BPF_SUB|BPF_K: 520 1.1 cgd A -= pc->k; 521 1.1 cgd continue; 522 1.21 perry 523 1.1 cgd case BPF_ALU|BPF_MUL|BPF_K: 524 1.1 cgd A *= pc->k; 525 1.1 cgd continue; 526 1.21 perry 527 1.1 cgd case BPF_ALU|BPF_DIV|BPF_K: 528 1.1 cgd A /= pc->k; 529 1.1 cgd continue; 530 1.21 perry 531 1.68 christos case BPF_ALU|BPF_MOD|BPF_K: 532 1.68 christos A %= pc->k; 533 1.68 christos continue; 534 1.68 christos 535 1.1 cgd case BPF_ALU|BPF_AND|BPF_K: 536 1.1 cgd A &= pc->k; 537 1.1 cgd continue; 538 1.21 perry 539 1.1 cgd case BPF_ALU|BPF_OR|BPF_K: 540 1.1 cgd A |= pc->k; 541 1.1 cgd continue; 542 1.1 cgd 543 1.68 christos case BPF_ALU|BPF_XOR|BPF_K: 544 1.68 christos A ^= pc->k; 545 1.68 christos continue; 546 1.68 christos 547 1.1 cgd case BPF_ALU|BPF_LSH|BPF_K: 548 1.1 cgd A <<= pc->k; 549 1.1 cgd continue; 550 1.1 cgd 551 1.1 cgd case BPF_ALU|BPF_RSH|BPF_K: 552 1.1 cgd A >>= pc->k; 553 1.1 cgd continue; 554 1.1 cgd 555 1.1 cgd case BPF_ALU|BPF_NEG: 556 1.1 cgd A = -A; 557 1.1 cgd continue; 558 1.1 cgd 559 1.1 cgd case BPF_MISC|BPF_TAX: 560 1.1 cgd X = A; 561 1.1 cgd continue; 562 1.1 cgd 563 1.1 cgd case BPF_MISC|BPF_TXA: 564 1.1 cgd A = X; 565 1.1 cgd continue; 566 1.56 rmind 567 1.56 rmind case BPF_MISC|BPF_COP: 568 1.56 rmind #ifdef _KERNEL 569 1.56 rmind if (pc->k < bc->nfuncs) { 570 1.56 rmind const bpf_copfunc_t fn = bc->copfuncs[pc->k]; 571 1.61 rmind A = fn(bc, args, A); 572 1.56 rmind continue; 573 1.56 rmind } 574 1.56 rmind #endif 575 1.56 rmind return 0; 576 1.56 rmind 577 1.56 rmind case BPF_MISC|BPF_COPX: 578 1.56 rmind #ifdef _KERNEL 579 1.56 rmind if (X < bc->nfuncs) { 580 1.56 rmind const bpf_copfunc_t fn = bc->copfuncs[X]; 581 1.61 rmind A = fn(bc, args, A); 582 1.56 rmind continue; 583 1.56 rmind } 584 1.56 rmind #endif 585 1.56 rmind return 0; 586 1.1 cgd } 587 1.1 cgd } 588 1.1 cgd } 589 1.1 cgd 590 1.1 cgd /* 591 1.1 cgd * Return true if the 'fcode' is a valid filter program. 592 1.1 cgd * The constraints are that each jump be forward and to a valid 593 1.34 christos * code, that memory accesses are within valid ranges (to the 594 1.34 christos * extent that this can be checked statically; loads of packet 595 1.34 christos * data have to be, and are, also checked at run time), and that 596 1.34 christos * the code terminates with either an accept or reject. 597 1.1 cgd * 598 1.1 cgd * The kernel needs to be able to verify an application's filter code. 599 1.1 cgd * Otherwise, a bogus program could easily crash the system. 600 1.1 cgd */ 601 1.42 christos 602 1.58 rmind #if defined(KERNEL) || defined(_KERNEL) 603 1.58 rmind 604 1.1 cgd int 605 1.39 mrg bpf_validate(const struct bpf_insn *f, int signed_len) 606 1.1 cgd { 607 1.62 alnsn return bpf_validate_ext(NULL, f, signed_len); 608 1.58 rmind } 609 1.58 rmind 610 1.58 rmind int 611 1.62 alnsn bpf_validate_ext(const bpf_ctx_t *bc, const struct bpf_insn *f, int signed_len) 612 1.58 rmind #else 613 1.73 christos __strong_alias(pcapint_validate_filter, bpf_validate) 614 1.58 rmind int 615 1.58 rmind bpf_validate(const struct bpf_insn *f, int signed_len) 616 1.58 rmind #endif 617 1.58 rmind { 618 1.45 enami u_int i, from, len, ok = 0; 619 1.38 christos const struct bpf_insn *p; 620 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 621 1.62 alnsn bpf_memword_init_t *mem, invalid; 622 1.46 christos size_t size; 623 1.63 rmind const size_t extwords = bc ? bc->extwords : 0; 624 1.63 rmind const size_t memwords = extwords ? extwords : BPF_MEMWORDS; 625 1.63 rmind const bpf_memword_init_t preinited = extwords ? bc->preinited : 0; 626 1.62 alnsn #else 627 1.62 alnsn const size_t memwords = BPF_MEMWORDS; 628 1.42 christos #endif 629 1.1 cgd 630 1.39 mrg len = (u_int)signed_len; 631 1.38 christos if (len < 1) 632 1.38 christos return 0; 633 1.38 christos #if defined(KERNEL) || defined(_KERNEL) 634 1.38 christos if (len > BPF_MAXINSNS) 635 1.24 rpaulo return 0; 636 1.38 christos #endif 637 1.70 alnsn if (f[len - 1].code != (BPF_RET|BPF_K) && 638 1.70 alnsn f[len - 1].code != (BPF_RET|BPF_A)) { 639 1.42 christos return 0; 640 1.69 alnsn } 641 1.42 christos 642 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 643 1.63 rmind /* Note: only the pre-initialised is valid on startup */ 644 1.44 christos mem = kmem_zalloc(size = sizeof(*mem) * len, KM_SLEEP); 645 1.63 rmind invalid = ~preinited; 646 1.42 christos #endif 647 1.24 rpaulo 648 1.1 cgd for (i = 0; i < len; ++i) { 649 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 650 1.42 christos /* blend in any invalid bits for current pc */ 651 1.42 christos invalid |= mem[i]; 652 1.42 christos #endif 653 1.24 rpaulo p = &f[i]; 654 1.24 rpaulo switch (BPF_CLASS(p->code)) { 655 1.1 cgd /* 656 1.24 rpaulo * Check that memory operations use valid addresses. 657 1.1 cgd */ 658 1.24 rpaulo case BPF_LD: 659 1.24 rpaulo case BPF_LDX: 660 1.24 rpaulo switch (BPF_MODE(p->code)) { 661 1.40 mrg case BPF_MEM: 662 1.38 christos /* 663 1.38 christos * There's no maximum packet data size 664 1.38 christos * in userland. The runtime packet length 665 1.38 christos * check suffices. 666 1.38 christos */ 667 1.38 christos #if defined(KERNEL) || defined(_KERNEL) 668 1.38 christos /* 669 1.38 christos * More strict check with actual packet length 670 1.38 christos * is done runtime. 671 1.38 christos */ 672 1.62 alnsn if (p->k >= memwords) 673 1.42 christos goto out; 674 1.42 christos /* check for current memory invalid */ 675 1.62 alnsn if (invalid & BPF_MEMWORD_INIT(p->k)) 676 1.42 christos goto out; 677 1.38 christos #endif 678 1.38 christos break; 679 1.40 mrg case BPF_ABS: 680 1.40 mrg case BPF_IND: 681 1.40 mrg case BPF_MSH: 682 1.40 mrg case BPF_IMM: 683 1.24 rpaulo case BPF_LEN: 684 1.24 rpaulo break; 685 1.24 rpaulo default: 686 1.42 christos goto out; 687 1.24 rpaulo } 688 1.24 rpaulo break; 689 1.24 rpaulo case BPF_ST: 690 1.24 rpaulo case BPF_STX: 691 1.62 alnsn if (p->k >= memwords) 692 1.42 christos goto out; 693 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 694 1.42 christos /* validate the memory word */ 695 1.64 rmind invalid &= ~BPF_MEMWORD_INIT(p->k); 696 1.42 christos #endif 697 1.24 rpaulo break; 698 1.24 rpaulo case BPF_ALU: 699 1.24 rpaulo switch (BPF_OP(p->code)) { 700 1.24 rpaulo case BPF_ADD: 701 1.24 rpaulo case BPF_SUB: 702 1.34 christos case BPF_MUL: 703 1.24 rpaulo case BPF_OR: 704 1.68 christos case BPF_XOR: 705 1.24 rpaulo case BPF_AND: 706 1.24 rpaulo case BPF_LSH: 707 1.24 rpaulo case BPF_RSH: 708 1.24 rpaulo case BPF_NEG: 709 1.24 rpaulo break; 710 1.24 rpaulo case BPF_DIV: 711 1.68 christos case BPF_MOD: 712 1.24 rpaulo /* 713 1.24 rpaulo * Check for constant division by 0. 714 1.24 rpaulo */ 715 1.41 mrg if (BPF_SRC(p->code) == BPF_K && p->k == 0) 716 1.42 christos goto out; 717 1.30 drochner break; 718 1.24 rpaulo default: 719 1.42 christos goto out; 720 1.1 cgd } 721 1.24 rpaulo break; 722 1.24 rpaulo case BPF_JMP: 723 1.24 rpaulo /* 724 1.24 rpaulo * Check that jumps are within the code block, 725 1.24 rpaulo * and that unconditional branches don't go 726 1.24 rpaulo * backwards as a result of an overflow. 727 1.24 rpaulo * Unconditional branches have a 32-bit offset, 728 1.24 rpaulo * so they could overflow; we check to make 729 1.24 rpaulo * sure they don't. Conditional branches have 730 1.24 rpaulo * an 8-bit offset, and the from address is <= 731 1.24 rpaulo * BPF_MAXINSNS, and we assume that BPF_MAXINSNS 732 1.24 rpaulo * is sufficiently small that adding 255 to it 733 1.24 rpaulo * won't overflow. 734 1.24 rpaulo * 735 1.24 rpaulo * We know that len is <= BPF_MAXINSNS, and we 736 1.24 rpaulo * assume that BPF_MAXINSNS is < the maximum size 737 1.24 rpaulo * of a u_int, so that i + 1 doesn't overflow. 738 1.38 christos * 739 1.38 christos * For userland, we don't know that the from 740 1.38 christos * or len are <= BPF_MAXINSNS, but we know that 741 1.38 christos * from <= len, and, except on a 64-bit system, 742 1.38 christos * it's unlikely that len, if it truly reflects 743 1.38 christos * the size of the program we've been handed, 744 1.38 christos * will be anywhere near the maximum size of 745 1.38 christos * a u_int. We also don't check for backward 746 1.38 christos * branches, as we currently support them in 747 1.38 christos * userland for the protochain operation. 748 1.24 rpaulo */ 749 1.24 rpaulo from = i + 1; 750 1.24 rpaulo switch (BPF_OP(p->code)) { 751 1.24 rpaulo case BPF_JA: 752 1.42 christos if (from + p->k >= len) 753 1.42 christos goto out; 754 1.38 christos #if defined(KERNEL) || defined(_KERNEL) 755 1.42 christos if (from + p->k < from) 756 1.42 christos goto out; 757 1.42 christos /* 758 1.42 christos * mark the currently invalid bits for the 759 1.42 christos * destination 760 1.42 christos */ 761 1.42 christos mem[from + p->k] |= invalid; 762 1.42 christos invalid = 0; 763 1.38 christos #endif 764 1.24 rpaulo break; 765 1.24 rpaulo case BPF_JEQ: 766 1.24 rpaulo case BPF_JGT: 767 1.24 rpaulo case BPF_JGE: 768 1.24 rpaulo case BPF_JSET: 769 1.38 christos if (from + p->jt >= len || from + p->jf >= len) 770 1.42 christos goto out; 771 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 772 1.42 christos /* 773 1.42 christos * mark the currently invalid bits for both 774 1.42 christos * possible jump destinations 775 1.42 christos */ 776 1.42 christos mem[from + p->jt] |= invalid; 777 1.42 christos mem[from + p->jf] |= invalid; 778 1.42 christos invalid = 0; 779 1.42 christos #endif 780 1.24 rpaulo break; 781 1.24 rpaulo default: 782 1.42 christos goto out; 783 1.24 rpaulo } 784 1.24 rpaulo break; 785 1.24 rpaulo case BPF_RET: 786 1.24 rpaulo break; 787 1.24 rpaulo case BPF_MISC: 788 1.59 rmind switch (BPF_MISCOP(p->code)) { 789 1.59 rmind case BPF_COP: 790 1.59 rmind case BPF_COPX: 791 1.59 rmind /* In-kernel COP use only. */ 792 1.62 alnsn #if defined(KERNEL) || defined(_KERNEL) 793 1.62 alnsn if (bc == NULL || bc->copfuncs == NULL) 794 1.62 alnsn goto out; 795 1.62 alnsn if (BPF_MISCOP(p->code) == BPF_COP && 796 1.62 alnsn p->k >= bc->nfuncs) { 797 1.62 alnsn goto out; 798 1.59 rmind } 799 1.59 rmind break; 800 1.62 alnsn #else 801 1.62 alnsn goto out; 802 1.62 alnsn #endif 803 1.59 rmind default: 804 1.59 rmind break; 805 1.59 rmind } 806 1.24 rpaulo break; 807 1.24 rpaulo default: 808 1.42 christos goto out; 809 1.1 cgd } 810 1.1 cgd } 811 1.42 christos ok = 1; 812 1.42 christos out: 813 1.42 christos #if defined(KERNEL) || defined(_KERNEL) 814 1.44 christos kmem_free(mem, size); 815 1.42 christos #endif 816 1.42 christos return ok; 817 1.1 cgd } 818 1.71 pgoyette 819 1.71 pgoyette /* Kernel module interface */ 820 1.71 pgoyette 821 1.71 pgoyette #ifdef _KERNEL 822 1.71 pgoyette MODULE(MODULE_CLASS_MISC, bpf_filter, NULL); 823 1.71 pgoyette 824 1.71 pgoyette static int 825 1.71 pgoyette bpf_filter_modcmd(modcmd_t cmd, void *opaque) 826 1.71 pgoyette { 827 1.71 pgoyette 828 1.71 pgoyette switch (cmd) { 829 1.71 pgoyette case MODULE_CMD_INIT: 830 1.71 pgoyette case MODULE_CMD_FINI: 831 1.71 pgoyette return 0; 832 1.71 pgoyette default: 833 1.71 pgoyette return ENOTTY; 834 1.71 pgoyette } 835 1.71 pgoyette } 836 1.71 pgoyette #endif 837