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