bpf_filter.c 11 KB

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