filter.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Linux Socket Filter - Kernel level socket filtering
  3.  *
  4.  * Author:
  5.  *     Jay Schulist <jschlst@samba.org>
  6.  *
  7.  * Based on the design of:
  8.  *     - The Berkeley Packet Filter
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License
  12.  * as published by the Free Software Foundation; either version
  13.  * 2 of the License, or (at your option) any later version.
  14.  *
  15.  * Andi Kleen - Fix a few bad bugs and races.
  16.  */
  17. #include <linux/config.h>
  18. #if defined(CONFIG_FILTER)
  19. #include <linux/module.h>
  20. #include <linux/types.h>
  21. #include <linux/sched.h>
  22. #include <linux/mm.h>
  23. #include <linux/fcntl.h>
  24. #include <linux/socket.h>
  25. #include <linux/in.h>
  26. #include <linux/inet.h>
  27. #include <linux/netdevice.h>
  28. #include <linux/if_packet.h>
  29. #include <net/ip.h>
  30. #include <net/protocol.h>
  31. #include <linux/skbuff.h>
  32. #include <net/sock.h>
  33. #include <linux/errno.h>
  34. #include <linux/timer.h>
  35. #include <asm/system.h>
  36. #include <asm/uaccess.h>
  37. #include <linux/filter.h>
  38. /* No hurry in this branch */
  39. static u8 *load_pointer(struct sk_buff *skb, int k)
  40. {
  41. u8 *ptr = NULL;
  42. if (k>=SKF_NET_OFF)
  43. ptr = skb->nh.raw + k - SKF_NET_OFF;
  44. else if (k>=SKF_LL_OFF)
  45. ptr = skb->mac.raw + k - SKF_LL_OFF;
  46. if (ptr >= skb->head && ptr < skb->tail)
  47. return ptr;
  48. return NULL;
  49. }
  50. /**
  51.  * sk_run_filter -  run a filter on a socket
  52.  * @skb: buffer to run the filter on
  53.  * @filter: filter to apply
  54.  * @flen: length of filter
  55.  *
  56.  * Decode and apply filter instructions to the skb->data.
  57.  * Return length to keep, 0 for none. skb is the data we are
  58.  * filtering, filter is the array of filter instructions, and
  59.  * len is the number of filter blocks in the array.
  60.  */
  61.  
  62. int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
  63. {
  64. unsigned char *data = skb->data;
  65. /* len is UNSIGNED. Byte wide insns relies only on implicit
  66.    type casts to prevent reading arbitrary memory locations.
  67.  */
  68. unsigned int len = skb->len-skb->data_len;
  69. struct sock_filter *fentry; /* We walk down these */
  70. u32 A = 0;     /* Accumulator */
  71. u32 X = 0;    /* Index Register */
  72. u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
  73. int k;
  74. int pc;
  75. /*
  76.  * Process array of filter instructions.
  77.  */
  78. for(pc = 0; pc < flen; pc++)
  79. {
  80. fentry = &filter[pc];
  81. switch(fentry->code)
  82. {
  83. case BPF_ALU|BPF_ADD|BPF_X:
  84. A += X;
  85. continue;
  86. case BPF_ALU|BPF_ADD|BPF_K:
  87. A += fentry->k;
  88. continue;
  89. case BPF_ALU|BPF_SUB|BPF_X:
  90. A -= X;
  91. continue;
  92. case BPF_ALU|BPF_SUB|BPF_K:
  93. A -= fentry->k;
  94. continue;
  95. case BPF_ALU|BPF_MUL|BPF_X:
  96. A *= X;
  97. continue;
  98. case BPF_ALU|BPF_MUL|BPF_K:
  99. A *= fentry->k;
  100. continue;
  101. case BPF_ALU|BPF_DIV|BPF_X:
  102. if(X == 0)
  103. return (0);
  104. A /= X;
  105. continue;
  106. case BPF_ALU|BPF_DIV|BPF_K:
  107. if(fentry->k == 0)
  108. return (0);
  109. A /= fentry->k;
  110. continue;
  111. case BPF_ALU|BPF_AND|BPF_X:
  112. A &= X;
  113. continue;
  114. case BPF_ALU|BPF_AND|BPF_K:
  115. A &= fentry->k;
  116. continue;
  117. case BPF_ALU|BPF_OR|BPF_X:
  118. A |= X;
  119. continue;
  120. case BPF_ALU|BPF_OR|BPF_K:
  121. A |= fentry->k;
  122. continue;
  123. case BPF_ALU|BPF_LSH|BPF_X:
  124. A <<= X;
  125. continue;
  126. case BPF_ALU|BPF_LSH|BPF_K:
  127. A <<= fentry->k;
  128. continue;
  129. case BPF_ALU|BPF_RSH|BPF_X:
  130. A >>= X;
  131. continue;
  132. case BPF_ALU|BPF_RSH|BPF_K:
  133. A >>= fentry->k;
  134. continue;
  135. case BPF_ALU|BPF_NEG:
  136. A = -A;
  137. continue;
  138. case BPF_JMP|BPF_JA:
  139. pc += fentry->k;
  140. continue;
  141. case BPF_JMP|BPF_JGT|BPF_K:
  142. pc += (A > fentry->k) ? fentry->jt : fentry->jf;
  143. continue;
  144. case BPF_JMP|BPF_JGE|BPF_K:
  145. pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
  146. continue;
  147. case BPF_JMP|BPF_JEQ|BPF_K:
  148. pc += (A == fentry->k) ? fentry->jt : fentry->jf;
  149. continue;
  150. case BPF_JMP|BPF_JSET|BPF_K:
  151. pc += (A & fentry->k) ? fentry->jt : fentry->jf;
  152. continue;
  153. case BPF_JMP|BPF_JGT|BPF_X:
  154. pc += (A > X) ? fentry->jt : fentry->jf;
  155. continue;
  156. case BPF_JMP|BPF_JGE|BPF_X:
  157. pc += (A >= X) ? fentry->jt : fentry->jf;
  158. continue;
  159. case BPF_JMP|BPF_JEQ|BPF_X:
  160. pc += (A == X) ? fentry->jt : fentry->jf;
  161. continue;
  162. case BPF_JMP|BPF_JSET|BPF_X:
  163. pc += (A & X) ? fentry->jt : fentry->jf;
  164. continue;
  165. case BPF_LD|BPF_W|BPF_ABS:
  166. k = fentry->k;
  167. load_w:
  168. if(k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
  169. A = ntohl(*(u32*)&data[k]);
  170. continue;
  171. }
  172. if (k<0) {
  173. u8 *ptr;
  174. if (k>=SKF_AD_OFF)
  175. break;
  176. if ((ptr = load_pointer(skb, k)) != NULL) {
  177. A = ntohl(*(u32*)ptr);
  178. continue;
  179. }
  180. } else {
  181. u32 tmp;
  182. if (!skb_copy_bits(skb, k, &tmp, 4)) {
  183. A = ntohl(tmp);
  184. continue;
  185. }
  186. }
  187. return 0;
  188. case BPF_LD|BPF_H|BPF_ABS:
  189. k = fentry->k;
  190. load_h:
  191. if(k >= 0 && (unsigned int) (k + sizeof(u16)) <= len) {
  192. A = ntohs(*(u16*)&data[k]);
  193. continue;
  194. }
  195. if (k<0) {
  196. u8 *ptr;
  197. if (k>=SKF_AD_OFF)
  198. break;
  199. if ((ptr = load_pointer(skb, k)) != NULL) {
  200. A = ntohs(*(u16*)ptr);
  201. continue;
  202. }
  203. } else {
  204. u16 tmp;
  205. if (!skb_copy_bits(skb, k, &tmp, 2)) {
  206. A = ntohs(tmp);
  207. continue;
  208. }
  209. }
  210. return 0;
  211. case BPF_LD|BPF_B|BPF_ABS:
  212. k = fentry->k;
  213. load_b:
  214. if(k >= 0 && (unsigned int)k < len) {
  215. A = data[k];
  216. continue;
  217. }
  218. if (k<0) {
  219. u8 *ptr;
  220. if (k>=SKF_AD_OFF)
  221. break;
  222. if ((ptr = load_pointer(skb, k)) != NULL) {
  223. A = *ptr;
  224. continue;
  225. }
  226. } else {
  227. u8 tmp;
  228. if (!skb_copy_bits(skb, k, &tmp, 1)) {
  229. A = tmp;
  230. continue;
  231. }
  232. }
  233. return 0;
  234. case BPF_LD|BPF_W|BPF_LEN:
  235. A = len;
  236. continue;
  237. case BPF_LDX|BPF_W|BPF_LEN:
  238. X = len;
  239. continue;
  240. case BPF_LD|BPF_W|BPF_IND:
  241. k = X + fentry->k;
  242. goto load_w;
  243.                        case BPF_LD|BPF_H|BPF_IND:
  244. k = X + fentry->k;
  245. goto load_h;
  246.                        case BPF_LD|BPF_B|BPF_IND:
  247. k = X + fentry->k;
  248. goto load_b;
  249. case BPF_LDX|BPF_B|BPF_MSH:
  250. k = fentry->k;
  251. if(k >= 0 && (unsigned int)k >= len)
  252. return (0);
  253. X = (data[k] & 0xf) << 2;
  254. continue;
  255. case BPF_LD|BPF_IMM:
  256. A = fentry->k;
  257. continue;
  258. case BPF_LDX|BPF_IMM:
  259. X = fentry->k;
  260. continue;
  261. case BPF_LD|BPF_MEM:
  262. A = mem[fentry->k];
  263. continue;
  264. case BPF_LDX|BPF_MEM:
  265. X = mem[fentry->k];
  266. continue;
  267. case BPF_MISC|BPF_TAX:
  268. X = A;
  269. continue;
  270. case BPF_MISC|BPF_TXA:
  271. A = X;
  272. continue;
  273. case BPF_RET|BPF_K:
  274. return ((unsigned int)fentry->k);
  275. case BPF_RET|BPF_A:
  276. return ((unsigned int)A);
  277. case BPF_ST:
  278. mem[fentry->k] = A;
  279. continue;
  280. case BPF_STX:
  281. mem[fentry->k] = X;
  282. continue;
  283. default:
  284. /* Invalid instruction counts as RET */
  285. return (0);
  286. }
  287. /* Handle ancillary data, which are impossible
  288.    (or very difficult) to get parsing packet contents.
  289.  */
  290. switch (k-SKF_AD_OFF) {
  291. case SKF_AD_PROTOCOL:
  292. A = htons(skb->protocol);
  293. continue;
  294. case SKF_AD_PKTTYPE:
  295. A = skb->pkt_type;
  296. continue;
  297. case SKF_AD_IFINDEX:
  298. A = skb->dev->ifindex;
  299. continue;
  300. default:
  301. return 0;
  302. }
  303. }
  304. return (0);
  305. }
  306. /**
  307.  * sk_chk_filter - verify socket filter code
  308.  * @filter: filter to verify
  309.  * @flen: length of filter
  310.  *
  311.  * Check the user's filter code. If we let some ugly
  312.  * filter code slip through kaboom! The filter must contain
  313.  * no references or jumps that are out of range, no illegal instructions
  314.  * and no backward jumps. It must end with a RET instruction
  315.  *
  316.  * Returns 0 if the rule set is legal or a negative errno code if not.
  317.  */
  318. int sk_chk_filter(struct sock_filter *filter, int flen)
  319. {
  320. struct sock_filter *ftest;
  321.         int pc;
  322. if ((unsigned int) flen >= (~0U / sizeof(struct sock_filter)))
  323. return -EINVAL;
  324.        /*
  325.         * Check the filter code now.
  326.         */
  327. for(pc = 0; pc < flen; pc++)
  328. {
  329. /*
  330.                  * All jumps are forward as they are not signed
  331.                  */
  332.                  
  333.                 ftest = &filter[pc];
  334. if(BPF_CLASS(ftest->code) == BPF_JMP)
  335. {
  336. /*
  337.  * But they mustn't jump off the end.
  338.  */
  339. if(BPF_OP(ftest->code) == BPF_JA)
  340. {
  341. /* Note, the large ftest->k might cause
  342.    loops. Compare this with conditional
  343.    jumps below, where offsets are limited. --ANK (981016)
  344.  */
  345. if (ftest->k >= (unsigned)(flen-pc-1))
  346. return -EINVAL;
  347. }
  348.                         else
  349. {
  350. /*
  351.  * For conditionals both must be safe
  352.  */
  353.   if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen)
  354. return -EINVAL;
  355. }
  356.                 }
  357.                 /*
  358.                  * Check that memory operations use valid addresses.
  359.                  */
  360.                  
  361.                 if (ftest->k >= BPF_MEMWORDS)
  362.                 {
  363.                  /*
  364.                   * But it might not be a memory operation...
  365.                   */
  366. switch (ftest->code) {
  367. case BPF_ST:
  368. case BPF_STX:
  369. case BPF_LD|BPF_MEM:
  370. case BPF_LDX|BPF_MEM:
  371.                  return -EINVAL;
  372. }
  373. }
  374.         }
  375. /*
  376.  * The program must end with a return. We don't care where they
  377.  * jumped within the script (its always forwards) but in the
  378.  * end they _will_ hit this.
  379.  */
  380.  
  381.         return (BPF_CLASS(filter[flen - 1].code) == BPF_RET)?0:-EINVAL;
  382. }
  383. /**
  384.  * sk_attach_filter - attach a socket filter
  385.  * @fprog: the filter program
  386.  * @sk: the socket to use
  387.  *
  388.  * Attach the user's filter code. We first run some sanity checks on
  389.  * it to make sure it does not explode on us later. If an error
  390.  * occurs or there is insufficient memory for the filter a negative
  391.  * errno code is returned. On success the return is zero.
  392.  */
  393. int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
  394. {
  395. struct sk_filter *fp; 
  396. unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
  397. int err;
  398. /* Make sure new filter is there and in the right amounts. */
  399.         if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS)
  400.                 return (-EINVAL);
  401. fp = (struct sk_filter *)sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
  402. if(fp == NULL)
  403. return (-ENOMEM);
  404. if (copy_from_user(fp->insns, fprog->filter, fsize)) {
  405. sock_kfree_s(sk, fp, fsize+sizeof(*fp)); 
  406. return -EFAULT;
  407. }
  408. atomic_set(&fp->refcnt, 1);
  409. fp->len = fprog->len;
  410. if ((err = sk_chk_filter(fp->insns, fp->len))==0) {
  411. struct sk_filter *old_fp;
  412. spin_lock_bh(&sk->lock.slock);
  413. old_fp = sk->filter;
  414. sk->filter = fp;
  415. spin_unlock_bh(&sk->lock.slock);
  416. fp = old_fp;
  417. }
  418. if (fp)
  419. sk_filter_release(sk, fp);
  420. return (err);
  421. }
  422. #endif /* CONFIG_FILTER */