LCOV - code coverage report
Current view: top level - net - bpf_filter.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 176 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 : bpf_mem_ldw(const void *mem, u_int32_t k, int *err)
      78             : {
      79           0 :         const struct bpf_mem *bm = mem;
      80             :         u_int32_t v;
      81             : 
      82           0 :         *err = 1;
      83             : 
      84           0 :         if (k + sizeof(v) > bm->len)
      85           0 :                 return (0);
      86             : 
      87           0 :         memcpy(&v, bm->pkt + k, sizeof(v));
      88             : 
      89           0 :         *err = 0;
      90           0 :         return ntohl(v);
      91           0 : }
      92             : 
      93             : Static u_int32_t
      94           0 : bpf_mem_ldh(const void *mem, u_int32_t k, int *err)
      95             : {
      96           0 :         const struct bpf_mem *bm = mem;
      97             :         u_int16_t v;
      98             : 
      99           0 :         *err = 1;
     100             : 
     101           0 :         if (k + sizeof(v) > bm->len)
     102           0 :                 return (0);
     103             : 
     104           0 :         memcpy(&v, bm->pkt + k, sizeof(v));
     105             : 
     106           0 :         *err = 0;
     107           0 :         return ntohs(v);
     108           0 : }
     109             : 
     110             : Static u_int32_t
     111           0 : bpf_mem_ldb(const void *mem, u_int32_t k, int *err)
     112             : {
     113           0 :         const struct bpf_mem *bm = mem;
     114             : 
     115           0 :         *err = 1;
     116             : 
     117           0 :         if (k >= bm->len)
     118           0 :                 return (0);
     119             : 
     120           0 :         *err = 0;
     121           0 :         return bm->pkt[k];
     122           0 : }
     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           0 : bpf_filter(const struct bpf_insn *pc, const u_char *pkt,
     131             :     u_int wirelen, u_int buflen)
     132             : {
     133           0 :         struct bpf_mem bm;
     134             : 
     135           0 :         bm.pkt = pkt;
     136           0 :         bm.len = buflen;
     137             : 
     138           0 :         return _bpf_filter(pc, &bpf_mem_ops, &bm, wirelen);
     139           0 : }
     140             : 
     141             : u_int
     142           0 : _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           0 :         int32_t mem[BPF_MEMWORDS];
     148           0 :         int err;
     149             : 
     150           0 :         if (pc == NULL) {
     151             :                 /*
     152             :                  * No filter means accept all.
     153             :                  */
     154           0 :                 return (u_int)-1;
     155             :         }
     156             : 
     157           0 :         memset(mem, 0, sizeof(mem));
     158             : 
     159           0 :         --pc;
     160           0 :         while (1) {
     161           0 :                 ++pc;
     162           0 :                 switch (pc->code) {
     163             : 
     164             :                 default:
     165             : #ifdef _KERNEL
     166           0 :                         return 0;
     167             : #else
     168             :                         abort();
     169             : #endif
     170             :                 case BPF_RET|BPF_K:
     171           0 :                         return (u_int)pc->k;
     172             : 
     173             :                 case BPF_RET|BPF_A:
     174           0 :                         return (u_int)A;
     175             : 
     176             :                 case BPF_LD|BPF_W|BPF_ABS:
     177           0 :                         A = ops->ldw(pkt, pc->k, &err);
     178           0 :                         if (err != 0)
     179           0 :                                 return 0;
     180           0 :                         continue;
     181             : 
     182             :                 case BPF_LD|BPF_H|BPF_ABS:
     183           0 :                         A = ops->ldh(pkt, pc->k, &err);
     184           0 :                         if (err != 0)
     185           0 :                                 return 0;
     186           0 :                         continue;
     187             : 
     188             :                 case BPF_LD|BPF_B|BPF_ABS:
     189           0 :                         A = ops->ldb(pkt, pc->k, &err);
     190           0 :                         if (err != 0)
     191           0 :                                 return 0;
     192           0 :                         continue;
     193             : 
     194             :                 case BPF_LD|BPF_W|BPF_LEN:
     195             :                         A = wirelen;
     196           0 :                         continue;
     197             : 
     198             :                 case BPF_LDX|BPF_W|BPF_LEN:
     199             :                         X = wirelen;
     200           0 :                         continue;
     201             : 
     202             :                 case BPF_LD|BPF_W|BPF_IND:
     203           0 :                         k = X + pc->k;
     204           0 :                         A = ops->ldw(pkt, k, &err);
     205           0 :                         if (err != 0)
     206           0 :                                 return 0;
     207           0 :                         continue;
     208             : 
     209             :                 case BPF_LD|BPF_H|BPF_IND:
     210           0 :                         k = X + pc->k;
     211           0 :                         A = ops->ldh(pkt, k, &err);
     212           0 :                         if (err != 0)
     213           0 :                                 return 0;
     214           0 :                         continue;
     215             : 
     216             :                 case BPF_LD|BPF_B|BPF_IND:
     217           0 :                         k = X + pc->k;
     218           0 :                         A = ops->ldb(pkt, k, &err);
     219           0 :                         if (err != 0)
     220           0 :                                 return 0;
     221           0 :                         continue;
     222             : 
     223             :                 case BPF_LDX|BPF_MSH|BPF_B:
     224           0 :                         X = ops->ldb(pkt, pc->k, &err);
     225           0 :                         if (err != 0)
     226           0 :                                 return 0;
     227           0 :                         X &= 0xf;
     228           0 :                         X <<= 2;
     229           0 :                         continue;
     230             : 
     231             :                 case BPF_LD|BPF_IMM:
     232           0 :                         A = pc->k;
     233           0 :                         continue;
     234             : 
     235             :                 case BPF_LDX|BPF_IMM:
     236           0 :                         X = pc->k;
     237           0 :                         continue;
     238             : 
     239             :                 case BPF_LD|BPF_MEM:
     240           0 :                         A = mem[pc->k];
     241           0 :                         continue;
     242             : 
     243             :                 case BPF_LDX|BPF_MEM:
     244           0 :                         X = mem[pc->k];
     245           0 :                         continue;
     246             : 
     247             :                 case BPF_ST:
     248           0 :                         mem[pc->k] = A;
     249           0 :                         continue;
     250             : 
     251             :                 case BPF_STX:
     252           0 :                         mem[pc->k] = X;
     253           0 :                         continue;
     254             : 
     255             :                 case BPF_JMP|BPF_JA:
     256           0 :                         pc += pc->k;
     257           0 :                         continue;
     258             : 
     259             :                 case BPF_JMP|BPF_JGT|BPF_K:
     260           0 :                         pc += (A > pc->k) ? pc->jt : pc->jf;
     261           0 :                         continue;
     262             : 
     263             :                 case BPF_JMP|BPF_JGE|BPF_K:
     264           0 :                         pc += (A >= pc->k) ? pc->jt : pc->jf;
     265           0 :                         continue;
     266             : 
     267             :                 case BPF_JMP|BPF_JEQ|BPF_K:
     268           0 :                         pc += (A == pc->k) ? pc->jt : pc->jf;
     269           0 :                         continue;
     270             : 
     271             :                 case BPF_JMP|BPF_JSET|BPF_K:
     272           0 :                         pc += (A & pc->k) ? pc->jt : pc->jf;
     273           0 :                         continue;
     274             : 
     275             :                 case BPF_JMP|BPF_JGT|BPF_X:
     276           0 :                         pc += (A > X) ? pc->jt : pc->jf;
     277           0 :                         continue;
     278             : 
     279             :                 case BPF_JMP|BPF_JGE|BPF_X:
     280           0 :                         pc += (A >= X) ? pc->jt : pc->jf;
     281           0 :                         continue;
     282             : 
     283             :                 case BPF_JMP|BPF_JEQ|BPF_X:
     284           0 :                         pc += (A == X) ? pc->jt : pc->jf;
     285           0 :                         continue;
     286             : 
     287             :                 case BPF_JMP|BPF_JSET|BPF_X:
     288           0 :                         pc += (A & X) ? pc->jt : pc->jf;
     289           0 :                         continue;
     290             : 
     291             :                 case BPF_ALU|BPF_ADD|BPF_X:
     292           0 :                         A += X;
     293           0 :                         continue;
     294             : 
     295             :                 case BPF_ALU|BPF_SUB|BPF_X:
     296           0 :                         A -= X;
     297           0 :                         continue;
     298             : 
     299             :                 case BPF_ALU|BPF_MUL|BPF_X:
     300           0 :                         A *= X;
     301           0 :                         continue;
     302             : 
     303             :                 case BPF_ALU|BPF_DIV|BPF_X:
     304           0 :                         if (X == 0)
     305           0 :                                 return 0;
     306           0 :                         A /= X;
     307           0 :                         continue;
     308             : 
     309             :                 case BPF_ALU|BPF_AND|BPF_X:
     310           0 :                         A &= X;
     311           0 :                         continue;
     312             : 
     313             :                 case BPF_ALU|BPF_OR|BPF_X:
     314           0 :                         A |= X;
     315           0 :                         continue;
     316             : 
     317             :                 case BPF_ALU|BPF_LSH|BPF_X:
     318           0 :                         A <<= X;
     319           0 :                         continue;
     320             : 
     321             :                 case BPF_ALU|BPF_RSH|BPF_X:
     322           0 :                         A >>= X;
     323           0 :                         continue;
     324             : 
     325             :                 case BPF_ALU|BPF_ADD|BPF_K:
     326           0 :                         A += pc->k;
     327           0 :                         continue;
     328             : 
     329             :                 case BPF_ALU|BPF_SUB|BPF_K:
     330           0 :                         A -= pc->k;
     331           0 :                         continue;
     332             : 
     333             :                 case BPF_ALU|BPF_MUL|BPF_K:
     334           0 :                         A *= pc->k;
     335           0 :                         continue;
     336             : 
     337             :                 case BPF_ALU|BPF_DIV|BPF_K:
     338           0 :                         A /= pc->k;
     339           0 :                         continue;
     340             : 
     341             :                 case BPF_ALU|BPF_AND|BPF_K:
     342           0 :                         A &= pc->k;
     343           0 :                         continue;
     344             : 
     345             :                 case BPF_ALU|BPF_OR|BPF_K:
     346           0 :                         A |= pc->k;
     347           0 :                         continue;
     348             : 
     349             :                 case BPF_ALU|BPF_LSH|BPF_K:
     350           0 :                         A <<= pc->k;
     351           0 :                         continue;
     352             : 
     353             :                 case BPF_ALU|BPF_RSH|BPF_K:
     354           0 :                         A >>= pc->k;
     355           0 :                         continue;
     356             : 
     357             :                 case BPF_ALU|BPF_NEG:
     358           0 :                         A = -A;
     359           0 :                         continue;
     360             : 
     361             :                 case BPF_MISC|BPF_TAX:
     362             :                         X = A;
     363           0 :                         continue;
     364             : 
     365             :                 case BPF_MISC|BPF_TXA:
     366             :                         A = X;
     367           0 :                         continue;
     368             :                 }
     369             :         }
     370           0 : }
     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           0 : bpf_validate(struct bpf_insn *f, int len)
     384             : {
     385             :         u_int i, from;
     386             :         struct bpf_insn *p;
     387             : 
     388           0 :         if (len < 1 || len > BPF_MAXINSNS)
     389           0 :                 return 0;
     390             : 
     391           0 :         for (i = 0; i < len; ++i) {
     392           0 :                 p = &f[i];
     393           0 :                 switch (BPF_CLASS(p->code)) {
     394             :                 /*
     395             :                  * Check that memory operations use valid addresses.
     396             :                  */
     397             :                 case BPF_LD:
     398             :                 case BPF_LDX:
     399           0 :                         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           0 :                                 if (p->k >= bpf_maxbufsize)
     410           0 :                                         return 0;
     411             :                                 break;
     412             :                         case BPF_MEM:
     413           0 :                                 if (p->k >= BPF_MEMWORDS)
     414           0 :                                         return 0;
     415             :                                 break;
     416             :                         case BPF_LEN:
     417             :                                 break;
     418             :                         default:
     419           0 :                                 return 0;
     420             :                         }
     421             :                         break;
     422             :                 case BPF_ST:
     423             :                 case BPF_STX:
     424           0 :                         if (p->k >= BPF_MEMWORDS)
     425           0 :                                 return 0;
     426             :                         break;
     427             :                 case BPF_ALU:
     428           0 :                         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           0 :                                 if (BPF_SRC(p->code) == BPF_K && p->k == 0)
     443           0 :                                         return 0;
     444             :                                 break;
     445             :                         default:
     446           0 :                                 return 0;
     447             :                         }
     448             :                         break;
     449             :                 case BPF_JMP:
     450             :                         /*
     451             :                          * Check that jumps are forward, and within
     452             :                          * the code block.
     453             :                          */
     454           0 :                         from = i + 1;
     455           0 :                         switch (BPF_OP(p->code)) {
     456             :                         case BPF_JA:
     457           0 :                                 if (from + p->k < from || from + p->k >= len)
     458           0 :                                         return 0;
     459             :                                 break;
     460             :                         case BPF_JEQ:
     461             :                         case BPF_JGT:
     462             :                         case BPF_JGE:
     463             :                         case BPF_JSET:
     464           0 :                                 if (from + p->jt >= len || from + p->jf >= len)
     465           0 :                                         return 0;
     466             :                                 break;
     467             :                         default:
     468           0 :                                 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           0 :         return BPF_CLASS(f[len - 1].code) == BPF_RET;
     481           0 : }
     482             : #endif

Generated by: LCOV version 1.13