Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.25-rc4 1548 lines 40 kB view raw
1/* 2 * ebtables 3 * 4 * Author: 5 * Bart De Schuymer <bdschuym@pandora.be> 6 * 7 * ebtables.c,v 2.0, July, 2002 8 * 9 * This code is stongly inspired on the iptables code which is 10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 15 * 2 of the License, or (at your option) any later version. 16 */ 17 18 19#include <linux/kmod.h> 20#include <linux/module.h> 21#include <linux/vmalloc.h> 22#include <linux/netfilter_bridge/ebtables.h> 23#include <linux/spinlock.h> 24#include <linux/mutex.h> 25#include <asm/uaccess.h> 26#include <linux/smp.h> 27#include <linux/cpumask.h> 28#include <net/sock.h> 29/* needed for logical [in,out]-dev filtering */ 30#include "../br_private.h" 31 32#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ 33 "report to author: "format, ## args) 34/* #define BUGPRINT(format, args...) */ 35#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ 36 ": out of memory: "format, ## args) 37/* #define MEMPRINT(format, args...) */ 38 39 40 41/* 42 * Each cpu has its own set of counters, so there is no need for write_lock in 43 * the softirq 44 * For reading or updating the counters, the user context needs to 45 * get a write_lock 46 */ 47 48/* The size of each set of counters is altered to get cache alignment */ 49#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 50#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter))) 51#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \ 52 COUNTER_OFFSET(n) * cpu)) 53 54 55 56static DEFINE_MUTEX(ebt_mutex); 57static LIST_HEAD(ebt_tables); 58static LIST_HEAD(ebt_targets); 59static LIST_HEAD(ebt_matches); 60static LIST_HEAD(ebt_watchers); 61 62static struct ebt_target ebt_standard_target = 63{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; 64 65static inline int ebt_do_watcher (struct ebt_entry_watcher *w, 66 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, 67 const struct net_device *out) 68{ 69 w->u.watcher->watcher(skb, hooknr, in, out, w->data, 70 w->watcher_size); 71 /* watchers don't give a verdict */ 72 return 0; 73} 74 75static inline int ebt_do_match (struct ebt_entry_match *m, 76 const struct sk_buff *skb, const struct net_device *in, 77 const struct net_device *out) 78{ 79 return m->u.match->match(skb, in, out, m->data, 80 m->match_size); 81} 82 83static inline int ebt_dev_check(char *entry, const struct net_device *device) 84{ 85 int i = 0; 86 const char *devname = device->name; 87 88 if (*entry == '\0') 89 return 0; 90 if (!device) 91 return 1; 92 /* 1 is the wildcard token */ 93 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i]) 94 i++; 95 return (devname[i] != entry[i] && entry[i] != 1); 96} 97 98#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg)) 99/* process standard matches */ 100static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h, 101 const struct net_device *in, const struct net_device *out) 102{ 103 int verdict, i; 104 105 if (e->bitmask & EBT_802_3) { 106 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO)) 107 return 1; 108 } else if (!(e->bitmask & EBT_NOPROTO) && 109 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO)) 110 return 1; 111 112 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN)) 113 return 1; 114 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) 115 return 1; 116 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check( 117 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN)) 118 return 1; 119 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check( 120 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT)) 121 return 1; 122 123 if (e->bitmask & EBT_SOURCEMAC) { 124 verdict = 0; 125 for (i = 0; i < 6; i++) 126 verdict |= (h->h_source[i] ^ e->sourcemac[i]) & 127 e->sourcemsk[i]; 128 if (FWINV2(verdict != 0, EBT_ISOURCE) ) 129 return 1; 130 } 131 if (e->bitmask & EBT_DESTMAC) { 132 verdict = 0; 133 for (i = 0; i < 6; i++) 134 verdict |= (h->h_dest[i] ^ e->destmac[i]) & 135 e->destmsk[i]; 136 if (FWINV2(verdict != 0, EBT_IDEST) ) 137 return 1; 138 } 139 return 0; 140} 141 142/* Do some firewalling */ 143unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, 144 const struct net_device *in, const struct net_device *out, 145 struct ebt_table *table) 146{ 147 int i, nentries; 148 struct ebt_entry *point; 149 struct ebt_counter *counter_base, *cb_base; 150 struct ebt_entry_target *t; 151 int verdict, sp = 0; 152 struct ebt_chainstack *cs; 153 struct ebt_entries *chaininfo; 154 char *base; 155 struct ebt_table_info *private; 156 157 read_lock_bh(&table->lock); 158 private = table->private; 159 cb_base = COUNTER_BASE(private->counters, private->nentries, 160 smp_processor_id()); 161 if (private->chainstack) 162 cs = private->chainstack[smp_processor_id()]; 163 else 164 cs = NULL; 165 chaininfo = private->hook_entry[hook]; 166 nentries = private->hook_entry[hook]->nentries; 167 point = (struct ebt_entry *)(private->hook_entry[hook]->data); 168 counter_base = cb_base + private->hook_entry[hook]->counter_offset; 169 /* base for chain jumps */ 170 base = private->entries; 171 i = 0; 172 while (i < nentries) { 173 if (ebt_basic_match(point, eth_hdr(skb), in, out)) 174 goto letscontinue; 175 176 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0) 177 goto letscontinue; 178 179 /* increase counter */ 180 (*(counter_base + i)).pcnt++; 181 (*(counter_base + i)).bcnt += skb->len; 182 183 /* these should only watch: not modify, nor tell us 184 what to do with the packet */ 185 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in, 186 out); 187 188 t = (struct ebt_entry_target *) 189 (((char *)point) + point->target_offset); 190 /* standard target */ 191 if (!t->u.target->target) 192 verdict = ((struct ebt_standard_target *)t)->verdict; 193 else 194 verdict = t->u.target->target(skb, hook, 195 in, out, t->data, t->target_size); 196 if (verdict == EBT_ACCEPT) { 197 read_unlock_bh(&table->lock); 198 return NF_ACCEPT; 199 } 200 if (verdict == EBT_DROP) { 201 read_unlock_bh(&table->lock); 202 return NF_DROP; 203 } 204 if (verdict == EBT_RETURN) { 205letsreturn: 206#ifdef CONFIG_NETFILTER_DEBUG 207 if (sp == 0) { 208 BUGPRINT("RETURN on base chain"); 209 /* act like this is EBT_CONTINUE */ 210 goto letscontinue; 211 } 212#endif 213 sp--; 214 /* put all the local variables right */ 215 i = cs[sp].n; 216 chaininfo = cs[sp].chaininfo; 217 nentries = chaininfo->nentries; 218 point = cs[sp].e; 219 counter_base = cb_base + 220 chaininfo->counter_offset; 221 continue; 222 } 223 if (verdict == EBT_CONTINUE) 224 goto letscontinue; 225#ifdef CONFIG_NETFILTER_DEBUG 226 if (verdict < 0) { 227 BUGPRINT("bogus standard verdict\n"); 228 read_unlock_bh(&table->lock); 229 return NF_DROP; 230 } 231#endif 232 /* jump to a udc */ 233 cs[sp].n = i + 1; 234 cs[sp].chaininfo = chaininfo; 235 cs[sp].e = (struct ebt_entry *) 236 (((char *)point) + point->next_offset); 237 i = 0; 238 chaininfo = (struct ebt_entries *) (base + verdict); 239#ifdef CONFIG_NETFILTER_DEBUG 240 if (chaininfo->distinguisher) { 241 BUGPRINT("jump to non-chain\n"); 242 read_unlock_bh(&table->lock); 243 return NF_DROP; 244 } 245#endif 246 nentries = chaininfo->nentries; 247 point = (struct ebt_entry *)chaininfo->data; 248 counter_base = cb_base + chaininfo->counter_offset; 249 sp++; 250 continue; 251letscontinue: 252 point = (struct ebt_entry *) 253 (((char *)point) + point->next_offset); 254 i++; 255 } 256 257 /* I actually like this :) */ 258 if (chaininfo->policy == EBT_RETURN) 259 goto letsreturn; 260 if (chaininfo->policy == EBT_ACCEPT) { 261 read_unlock_bh(&table->lock); 262 return NF_ACCEPT; 263 } 264 read_unlock_bh(&table->lock); 265 return NF_DROP; 266} 267 268/* If it succeeds, returns element and locks mutex */ 269static inline void * 270find_inlist_lock_noload(struct list_head *head, const char *name, int *error, 271 struct mutex *mutex) 272{ 273 struct { 274 struct list_head list; 275 char name[EBT_FUNCTION_MAXNAMELEN]; 276 } *e; 277 278 *error = mutex_lock_interruptible(mutex); 279 if (*error != 0) 280 return NULL; 281 282 list_for_each_entry(e, head, list) { 283 if (strcmp(e->name, name) == 0) 284 return e; 285 } 286 *error = -ENOENT; 287 mutex_unlock(mutex); 288 return NULL; 289} 290 291#ifndef CONFIG_KMOD 292#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) 293#else 294static void * 295find_inlist_lock(struct list_head *head, const char *name, const char *prefix, 296 int *error, struct mutex *mutex) 297{ 298 void *ret; 299 300 ret = find_inlist_lock_noload(head, name, error, mutex); 301 if (!ret) { 302 request_module("%s%s", prefix, name); 303 ret = find_inlist_lock_noload(head, name, error, mutex); 304 } 305 return ret; 306} 307#endif 308 309static inline struct ebt_table * 310find_table_lock(const char *name, int *error, struct mutex *mutex) 311{ 312 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); 313} 314 315static inline struct ebt_match * 316find_match_lock(const char *name, int *error, struct mutex *mutex) 317{ 318 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); 319} 320 321static inline struct ebt_watcher * 322find_watcher_lock(const char *name, int *error, struct mutex *mutex) 323{ 324 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); 325} 326 327static inline struct ebt_target * 328find_target_lock(const char *name, int *error, struct mutex *mutex) 329{ 330 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); 331} 332 333static inline int 334ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, 335 const char *name, unsigned int hookmask, unsigned int *cnt) 336{ 337 struct ebt_match *match; 338 size_t left = ((char *)e + e->watchers_offset) - (char *)m; 339 int ret; 340 341 if (left < sizeof(struct ebt_entry_match) || 342 left - sizeof(struct ebt_entry_match) < m->match_size) 343 return -EINVAL; 344 match = find_match_lock(m->u.name, &ret, &ebt_mutex); 345 if (!match) 346 return ret; 347 m->u.match = match; 348 if (!try_module_get(match->me)) { 349 mutex_unlock(&ebt_mutex); 350 return -ENOENT; 351 } 352 mutex_unlock(&ebt_mutex); 353 if (match->check && 354 match->check(name, hookmask, e, m->data, m->match_size) != 0) { 355 BUGPRINT("match->check failed\n"); 356 module_put(match->me); 357 return -EINVAL; 358 } 359 (*cnt)++; 360 return 0; 361} 362 363static inline int 364ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, 365 const char *name, unsigned int hookmask, unsigned int *cnt) 366{ 367 struct ebt_watcher *watcher; 368 size_t left = ((char *)e + e->target_offset) - (char *)w; 369 int ret; 370 371 if (left < sizeof(struct ebt_entry_watcher) || 372 left - sizeof(struct ebt_entry_watcher) < w->watcher_size) 373 return -EINVAL; 374 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); 375 if (!watcher) 376 return ret; 377 w->u.watcher = watcher; 378 if (!try_module_get(watcher->me)) { 379 mutex_unlock(&ebt_mutex); 380 return -ENOENT; 381 } 382 mutex_unlock(&ebt_mutex); 383 if (watcher->check && 384 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { 385 BUGPRINT("watcher->check failed\n"); 386 module_put(watcher->me); 387 return -EINVAL; 388 } 389 (*cnt)++; 390 return 0; 391} 392 393static int ebt_verify_pointers(struct ebt_replace *repl, 394 struct ebt_table_info *newinfo) 395{ 396 unsigned int limit = repl->entries_size; 397 unsigned int valid_hooks = repl->valid_hooks; 398 unsigned int offset = 0; 399 int i; 400 401 for (i = 0; i < NF_BR_NUMHOOKS; i++) 402 newinfo->hook_entry[i] = NULL; 403 404 newinfo->entries_size = repl->entries_size; 405 newinfo->nentries = repl->nentries; 406 407 while (offset < limit) { 408 size_t left = limit - offset; 409 struct ebt_entry *e = (void *)newinfo->entries + offset; 410 411 if (left < sizeof(unsigned int)) 412 break; 413 414 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 415 if ((valid_hooks & (1 << i)) == 0) 416 continue; 417 if ((char __user *)repl->hook_entry[i] == 418 repl->entries + offset) 419 break; 420 } 421 422 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { 423 if (e->bitmask != 0) { 424 /* we make userspace set this right, 425 so there is no misunderstanding */ 426 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " 427 "in distinguisher\n"); 428 return -EINVAL; 429 } 430 if (i != NF_BR_NUMHOOKS) 431 newinfo->hook_entry[i] = (struct ebt_entries *)e; 432 if (left < sizeof(struct ebt_entries)) 433 break; 434 offset += sizeof(struct ebt_entries); 435 } else { 436 if (left < sizeof(struct ebt_entry)) 437 break; 438 if (left < e->next_offset) 439 break; 440 offset += e->next_offset; 441 } 442 } 443 if (offset != limit) { 444 BUGPRINT("entries_size too small\n"); 445 return -EINVAL; 446 } 447 448 /* check if all valid hooks have a chain */ 449 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 450 if (!newinfo->hook_entry[i] && 451 (valid_hooks & (1 << i))) { 452 BUGPRINT("Valid hook without chain\n"); 453 return -EINVAL; 454 } 455 } 456 return 0; 457} 458 459/* 460 * this one is very careful, as it is the first function 461 * to parse the userspace data 462 */ 463static inline int 464ebt_check_entry_size_and_hooks(struct ebt_entry *e, 465 struct ebt_table_info *newinfo, 466 unsigned int *n, unsigned int *cnt, 467 unsigned int *totalcnt, unsigned int *udc_cnt) 468{ 469 int i; 470 471 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 472 if ((void *)e == (void *)newinfo->hook_entry[i]) 473 break; 474 } 475 /* beginning of a new chain 476 if i == NF_BR_NUMHOOKS it must be a user defined chain */ 477 if (i != NF_BR_NUMHOOKS || !e->bitmask) { 478 /* this checks if the previous chain has as many entries 479 as it said it has */ 480 if (*n != *cnt) { 481 BUGPRINT("nentries does not equal the nr of entries " 482 "in the chain\n"); 483 return -EINVAL; 484 } 485 if (((struct ebt_entries *)e)->policy != EBT_DROP && 486 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { 487 /* only RETURN from udc */ 488 if (i != NF_BR_NUMHOOKS || 489 ((struct ebt_entries *)e)->policy != EBT_RETURN) { 490 BUGPRINT("bad policy\n"); 491 return -EINVAL; 492 } 493 } 494 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */ 495 (*udc_cnt)++; 496 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) { 497 BUGPRINT("counter_offset != totalcnt"); 498 return -EINVAL; 499 } 500 *n = ((struct ebt_entries *)e)->nentries; 501 *cnt = 0; 502 return 0; 503 } 504 /* a plain old entry, heh */ 505 if (sizeof(struct ebt_entry) > e->watchers_offset || 506 e->watchers_offset > e->target_offset || 507 e->target_offset >= e->next_offset) { 508 BUGPRINT("entry offsets not in right order\n"); 509 return -EINVAL; 510 } 511 /* this is not checked anywhere else */ 512 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) { 513 BUGPRINT("target size too small\n"); 514 return -EINVAL; 515 } 516 (*cnt)++; 517 (*totalcnt)++; 518 return 0; 519} 520 521struct ebt_cl_stack 522{ 523 struct ebt_chainstack cs; 524 int from; 525 unsigned int hookmask; 526}; 527 528/* 529 * we need these positions to check that the jumps to a different part of the 530 * entries is a jump to the beginning of a new chain. 531 */ 532static inline int 533ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, 534 unsigned int *n, struct ebt_cl_stack *udc) 535{ 536 int i; 537 538 /* we're only interested in chain starts */ 539 if (e->bitmask) 540 return 0; 541 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 542 if (newinfo->hook_entry[i] == (struct ebt_entries *)e) 543 break; 544 } 545 /* only care about udc */ 546 if (i != NF_BR_NUMHOOKS) 547 return 0; 548 549 udc[*n].cs.chaininfo = (struct ebt_entries *)e; 550 /* these initialisations are depended on later in check_chainloops() */ 551 udc[*n].cs.n = 0; 552 udc[*n].hookmask = 0; 553 554 (*n)++; 555 return 0; 556} 557 558static inline int 559ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) 560{ 561 if (i && (*i)-- == 0) 562 return 1; 563 if (m->u.match->destroy) 564 m->u.match->destroy(m->data, m->match_size); 565 module_put(m->u.match->me); 566 567 return 0; 568} 569 570static inline int 571ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) 572{ 573 if (i && (*i)-- == 0) 574 return 1; 575 if (w->u.watcher->destroy) 576 w->u.watcher->destroy(w->data, w->watcher_size); 577 module_put(w->u.watcher->me); 578 579 return 0; 580} 581 582static inline int 583ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 584{ 585 struct ebt_entry_target *t; 586 587 if (e->bitmask == 0) 588 return 0; 589 /* we're done */ 590 if (cnt && (*cnt)-- == 0) 591 return 1; 592 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); 593 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); 594 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 595 if (t->u.target->destroy) 596 t->u.target->destroy(t->data, t->target_size); 597 module_put(t->u.target->me); 598 599 return 0; 600} 601 602static inline int 603ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, 604 const char *name, unsigned int *cnt, 605 struct ebt_cl_stack *cl_s, unsigned int udc_cnt) 606{ 607 struct ebt_entry_target *t; 608 struct ebt_target *target; 609 unsigned int i, j, hook = 0, hookmask = 0; 610 size_t gap; 611 int ret; 612 613 /* don't mess with the struct ebt_entries */ 614 if (e->bitmask == 0) 615 return 0; 616 617 if (e->bitmask & ~EBT_F_MASK) { 618 BUGPRINT("Unknown flag for bitmask\n"); 619 return -EINVAL; 620 } 621 if (e->invflags & ~EBT_INV_MASK) { 622 BUGPRINT("Unknown flag for inv bitmask\n"); 623 return -EINVAL; 624 } 625 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) { 626 BUGPRINT("NOPROTO & 802_3 not allowed\n"); 627 return -EINVAL; 628 } 629 /* what hook do we belong to? */ 630 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 631 if (!newinfo->hook_entry[i]) 632 continue; 633 if ((char *)newinfo->hook_entry[i] < (char *)e) 634 hook = i; 635 else 636 break; 637 } 638 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on 639 a base chain */ 640 if (i < NF_BR_NUMHOOKS) 641 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); 642 else { 643 for (i = 0; i < udc_cnt; i++) 644 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e) 645 break; 646 if (i == 0) 647 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); 648 else 649 hookmask = cl_s[i - 1].hookmask; 650 } 651 i = 0; 652 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); 653 if (ret != 0) 654 goto cleanup_matches; 655 j = 0; 656 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); 657 if (ret != 0) 658 goto cleanup_watchers; 659 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 660 gap = e->next_offset - e->target_offset; 661 target = find_target_lock(t->u.name, &ret, &ebt_mutex); 662 if (!target) 663 goto cleanup_watchers; 664 if (!try_module_get(target->me)) { 665 mutex_unlock(&ebt_mutex); 666 ret = -ENOENT; 667 goto cleanup_watchers; 668 } 669 mutex_unlock(&ebt_mutex); 670 671 t->u.target = target; 672 if (t->u.target == &ebt_standard_target) { 673 if (gap < sizeof(struct ebt_standard_target)) { 674 BUGPRINT("Standard target size too big\n"); 675 ret = -EFAULT; 676 goto cleanup_watchers; 677 } 678 if (((struct ebt_standard_target *)t)->verdict < 679 -NUM_STANDARD_TARGETS) { 680 BUGPRINT("Invalid standard target\n"); 681 ret = -EFAULT; 682 goto cleanup_watchers; 683 } 684 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || 685 (t->u.target->check && 686 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ 687 module_put(t->u.target->me); 688 ret = -EFAULT; 689 goto cleanup_watchers; 690 } 691 (*cnt)++; 692 return 0; 693cleanup_watchers: 694 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j); 695cleanup_matches: 696 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i); 697 return ret; 698} 699 700/* 701 * checks for loops and sets the hook mask for udc 702 * the hook mask for udc tells us from which base chains the udc can be 703 * accessed. This mask is a parameter to the check() functions of the extensions 704 */ 705static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s, 706 unsigned int udc_cnt, unsigned int hooknr, char *base) 707{ 708 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict; 709 struct ebt_entry *e = (struct ebt_entry *)chain->data; 710 struct ebt_entry_target *t; 711 712 while (pos < nentries || chain_nr != -1) { 713 /* end of udc, go back one 'recursion' step */ 714 if (pos == nentries) { 715 /* put back values of the time when this chain was called */ 716 e = cl_s[chain_nr].cs.e; 717 if (cl_s[chain_nr].from != -1) 718 nentries = 719 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries; 720 else 721 nentries = chain->nentries; 722 pos = cl_s[chain_nr].cs.n; 723 /* make sure we won't see a loop that isn't one */ 724 cl_s[chain_nr].cs.n = 0; 725 chain_nr = cl_s[chain_nr].from; 726 if (pos == nentries) 727 continue; 728 } 729 t = (struct ebt_entry_target *) 730 (((char *)e) + e->target_offset); 731 if (strcmp(t->u.name, EBT_STANDARD_TARGET)) 732 goto letscontinue; 733 if (e->target_offset + sizeof(struct ebt_standard_target) > 734 e->next_offset) { 735 BUGPRINT("Standard target size too big\n"); 736 return -1; 737 } 738 verdict = ((struct ebt_standard_target *)t)->verdict; 739 if (verdict >= 0) { /* jump to another chain */ 740 struct ebt_entries *hlp2 = 741 (struct ebt_entries *)(base + verdict); 742 for (i = 0; i < udc_cnt; i++) 743 if (hlp2 == cl_s[i].cs.chaininfo) 744 break; 745 /* bad destination or loop */ 746 if (i == udc_cnt) { 747 BUGPRINT("bad destination\n"); 748 return -1; 749 } 750 if (cl_s[i].cs.n) { 751 BUGPRINT("loop\n"); 752 return -1; 753 } 754 if (cl_s[i].hookmask & (1 << hooknr)) 755 goto letscontinue; 756 /* this can't be 0, so the loop test is correct */ 757 cl_s[i].cs.n = pos + 1; 758 pos = 0; 759 cl_s[i].cs.e = ((void *)e + e->next_offset); 760 e = (struct ebt_entry *)(hlp2->data); 761 nentries = hlp2->nentries; 762 cl_s[i].from = chain_nr; 763 chain_nr = i; 764 /* this udc is accessible from the base chain for hooknr */ 765 cl_s[i].hookmask |= (1 << hooknr); 766 continue; 767 } 768letscontinue: 769 e = (void *)e + e->next_offset; 770 pos++; 771 } 772 return 0; 773} 774 775/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */ 776static int translate_table(char *name, struct ebt_table_info *newinfo) 777{ 778 unsigned int i, j, k, udc_cnt; 779 int ret; 780 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */ 781 782 i = 0; 783 while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i]) 784 i++; 785 if (i == NF_BR_NUMHOOKS) { 786 BUGPRINT("No valid hooks specified\n"); 787 return -EINVAL; 788 } 789 if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) { 790 BUGPRINT("Chains don't start at beginning\n"); 791 return -EINVAL; 792 } 793 /* make sure chains are ordered after each other in same order 794 as their corresponding hooks */ 795 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) { 796 if (!newinfo->hook_entry[j]) 797 continue; 798 if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) { 799 BUGPRINT("Hook order must be followed\n"); 800 return -EINVAL; 801 } 802 i = j; 803 } 804 805 /* do some early checkings and initialize some things */ 806 i = 0; /* holds the expected nr. of entries for the chain */ 807 j = 0; /* holds the up to now counted entries for the chain */ 808 k = 0; /* holds the total nr. of entries, should equal 809 newinfo->nentries afterwards */ 810 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */ 811 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 812 ebt_check_entry_size_and_hooks, newinfo, 813 &i, &j, &k, &udc_cnt); 814 815 if (ret != 0) 816 return ret; 817 818 if (i != j) { 819 BUGPRINT("nentries does not equal the nr of entries in the " 820 "(last) chain\n"); 821 return -EINVAL; 822 } 823 if (k != newinfo->nentries) { 824 BUGPRINT("Total nentries is wrong\n"); 825 return -EINVAL; 826 } 827 828 /* get the location of the udc, put them in an array 829 while we're at it, allocate the chainstack */ 830 if (udc_cnt) { 831 /* this will get free'd in do_replace()/ebt_register_table() 832 if an error occurs */ 833 newinfo->chainstack = 834 vmalloc(nr_cpu_ids * sizeof(*(newinfo->chainstack))); 835 if (!newinfo->chainstack) 836 return -ENOMEM; 837 for_each_possible_cpu(i) { 838 newinfo->chainstack[i] = 839 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0]))); 840 if (!newinfo->chainstack[i]) { 841 while (i) 842 vfree(newinfo->chainstack[--i]); 843 vfree(newinfo->chainstack); 844 newinfo->chainstack = NULL; 845 return -ENOMEM; 846 } 847 } 848 849 cl_s = vmalloc(udc_cnt * sizeof(*cl_s)); 850 if (!cl_s) 851 return -ENOMEM; 852 i = 0; /* the i'th udc */ 853 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 854 ebt_get_udc_positions, newinfo, &i, cl_s); 855 /* sanity check */ 856 if (i != udc_cnt) { 857 BUGPRINT("i != udc_cnt\n"); 858 vfree(cl_s); 859 return -EFAULT; 860 } 861 } 862 863 /* Check for loops */ 864 for (i = 0; i < NF_BR_NUMHOOKS; i++) 865 if (newinfo->hook_entry[i]) 866 if (check_chainloops(newinfo->hook_entry[i], 867 cl_s, udc_cnt, i, newinfo->entries)) { 868 vfree(cl_s); 869 return -EINVAL; 870 } 871 872 /* we now know the following (along with E=mc²): 873 - the nr of entries in each chain is right 874 - the size of the allocated space is right 875 - all valid hooks have a corresponding chain 876 - there are no loops 877 - wrong data can still be on the level of a single entry 878 - could be there are jumps to places that are not the 879 beginning of a chain. This can only occur in chains that 880 are not accessible from any base chains, so we don't care. */ 881 882 /* used to know what we need to clean up if something goes wrong */ 883 i = 0; 884 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 885 ebt_check_entry, newinfo, name, &i, cl_s, udc_cnt); 886 if (ret != 0) { 887 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 888 ebt_cleanup_entry, &i); 889 } 890 vfree(cl_s); 891 return ret; 892} 893 894/* called under write_lock */ 895static void get_counters(struct ebt_counter *oldcounters, 896 struct ebt_counter *counters, unsigned int nentries) 897{ 898 int i, cpu; 899 struct ebt_counter *counter_base; 900 901 /* counters of cpu 0 */ 902 memcpy(counters, oldcounters, 903 sizeof(struct ebt_counter) * nentries); 904 905 /* add other counters to those of cpu 0 */ 906 for_each_possible_cpu(cpu) { 907 if (cpu == 0) 908 continue; 909 counter_base = COUNTER_BASE(oldcounters, nentries, cpu); 910 for (i = 0; i < nentries; i++) { 911 counters[i].pcnt += counter_base[i].pcnt; 912 counters[i].bcnt += counter_base[i].bcnt; 913 } 914 } 915} 916 917/* replace the table */ 918static int do_replace(void __user *user, unsigned int len) 919{ 920 int ret, i, countersize; 921 struct ebt_table_info *newinfo; 922 struct ebt_replace tmp; 923 struct ebt_table *t; 924 struct ebt_counter *counterstmp = NULL; 925 /* used to be able to unlock earlier */ 926 struct ebt_table_info *table; 927 928 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 929 return -EFAULT; 930 931 if (len != sizeof(tmp) + tmp.entries_size) { 932 BUGPRINT("Wrong len argument\n"); 933 return -EINVAL; 934 } 935 936 if (tmp.entries_size == 0) { 937 BUGPRINT("Entries_size never zero\n"); 938 return -EINVAL; 939 } 940 /* overflow check */ 941 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS - 942 SMP_CACHE_BYTES) / sizeof(struct ebt_counter)) 943 return -ENOMEM; 944 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) 945 return -ENOMEM; 946 947 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids; 948 newinfo = vmalloc(sizeof(*newinfo) + countersize); 949 if (!newinfo) 950 return -ENOMEM; 951 952 if (countersize) 953 memset(newinfo->counters, 0, countersize); 954 955 newinfo->entries = vmalloc(tmp.entries_size); 956 if (!newinfo->entries) { 957 ret = -ENOMEM; 958 goto free_newinfo; 959 } 960 if (copy_from_user( 961 newinfo->entries, tmp.entries, tmp.entries_size) != 0) { 962 BUGPRINT("Couldn't copy entries from userspace\n"); 963 ret = -EFAULT; 964 goto free_entries; 965 } 966 967 /* the user wants counters back 968 the check on the size is done later, when we have the lock */ 969 if (tmp.num_counters) { 970 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp)); 971 if (!counterstmp) { 972 ret = -ENOMEM; 973 goto free_entries; 974 } 975 } 976 else 977 counterstmp = NULL; 978 979 /* this can get initialized by translate_table() */ 980 newinfo->chainstack = NULL; 981 ret = ebt_verify_pointers(&tmp, newinfo); 982 if (ret != 0) 983 goto free_counterstmp; 984 985 ret = translate_table(tmp.name, newinfo); 986 987 if (ret != 0) 988 goto free_counterstmp; 989 990 t = find_table_lock(tmp.name, &ret, &ebt_mutex); 991 if (!t) { 992 ret = -ENOENT; 993 goto free_iterate; 994 } 995 996 /* the table doesn't like it */ 997 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks))) 998 goto free_unlock; 999 1000 if (tmp.num_counters && tmp.num_counters != t->private->nentries) { 1001 BUGPRINT("Wrong nr. of counters requested\n"); 1002 ret = -EINVAL; 1003 goto free_unlock; 1004 } 1005 1006 /* we have the mutex lock, so no danger in reading this pointer */ 1007 table = t->private; 1008 /* make sure the table can only be rmmod'ed if it contains no rules */ 1009 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) { 1010 ret = -ENOENT; 1011 goto free_unlock; 1012 } else if (table->nentries && !newinfo->nentries) 1013 module_put(t->me); 1014 /* we need an atomic snapshot of the counters */ 1015 write_lock_bh(&t->lock); 1016 if (tmp.num_counters) 1017 get_counters(t->private->counters, counterstmp, 1018 t->private->nentries); 1019 1020 t->private = newinfo; 1021 write_unlock_bh(&t->lock); 1022 mutex_unlock(&ebt_mutex); 1023 /* so, a user can change the chains while having messed up her counter 1024 allocation. Only reason why this is done is because this way the lock 1025 is held only once, while this doesn't bring the kernel into a 1026 dangerous state. */ 1027 if (tmp.num_counters && 1028 copy_to_user(tmp.counters, counterstmp, 1029 tmp.num_counters * sizeof(struct ebt_counter))) { 1030 BUGPRINT("Couldn't copy counters to userspace\n"); 1031 ret = -EFAULT; 1032 } 1033 else 1034 ret = 0; 1035 1036 /* decrease module count and free resources */ 1037 EBT_ENTRY_ITERATE(table->entries, table->entries_size, 1038 ebt_cleanup_entry, NULL); 1039 1040 vfree(table->entries); 1041 if (table->chainstack) { 1042 for_each_possible_cpu(i) 1043 vfree(table->chainstack[i]); 1044 vfree(table->chainstack); 1045 } 1046 vfree(table); 1047 1048 vfree(counterstmp); 1049 return ret; 1050 1051free_unlock: 1052 mutex_unlock(&ebt_mutex); 1053free_iterate: 1054 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 1055 ebt_cleanup_entry, NULL); 1056free_counterstmp: 1057 vfree(counterstmp); 1058 /* can be initialized in translate_table() */ 1059 if (newinfo->chainstack) { 1060 for_each_possible_cpu(i) 1061 vfree(newinfo->chainstack[i]); 1062 vfree(newinfo->chainstack); 1063 } 1064free_entries: 1065 vfree(newinfo->entries); 1066free_newinfo: 1067 vfree(newinfo); 1068 return ret; 1069} 1070 1071int ebt_register_target(struct ebt_target *target) 1072{ 1073 struct ebt_target *t; 1074 int ret; 1075 1076 ret = mutex_lock_interruptible(&ebt_mutex); 1077 if (ret != 0) 1078 return ret; 1079 list_for_each_entry(t, &ebt_targets, list) { 1080 if (strcmp(t->name, target->name) == 0) { 1081 mutex_unlock(&ebt_mutex); 1082 return -EEXIST; 1083 } 1084 } 1085 list_add(&target->list, &ebt_targets); 1086 mutex_unlock(&ebt_mutex); 1087 1088 return 0; 1089} 1090 1091void ebt_unregister_target(struct ebt_target *target) 1092{ 1093 mutex_lock(&ebt_mutex); 1094 list_del(&target->list); 1095 mutex_unlock(&ebt_mutex); 1096} 1097 1098int ebt_register_match(struct ebt_match *match) 1099{ 1100 struct ebt_match *m; 1101 int ret; 1102 1103 ret = mutex_lock_interruptible(&ebt_mutex); 1104 if (ret != 0) 1105 return ret; 1106 list_for_each_entry(m, &ebt_matches, list) { 1107 if (strcmp(m->name, match->name) == 0) { 1108 mutex_unlock(&ebt_mutex); 1109 return -EEXIST; 1110 } 1111 } 1112 list_add(&match->list, &ebt_matches); 1113 mutex_unlock(&ebt_mutex); 1114 1115 return 0; 1116} 1117 1118void ebt_unregister_match(struct ebt_match *match) 1119{ 1120 mutex_lock(&ebt_mutex); 1121 list_del(&match->list); 1122 mutex_unlock(&ebt_mutex); 1123} 1124 1125int ebt_register_watcher(struct ebt_watcher *watcher) 1126{ 1127 struct ebt_watcher *w; 1128 int ret; 1129 1130 ret = mutex_lock_interruptible(&ebt_mutex); 1131 if (ret != 0) 1132 return ret; 1133 list_for_each_entry(w, &ebt_watchers, list) { 1134 if (strcmp(w->name, watcher->name) == 0) { 1135 mutex_unlock(&ebt_mutex); 1136 return -EEXIST; 1137 } 1138 } 1139 list_add(&watcher->list, &ebt_watchers); 1140 mutex_unlock(&ebt_mutex); 1141 1142 return 0; 1143} 1144 1145void ebt_unregister_watcher(struct ebt_watcher *watcher) 1146{ 1147 mutex_lock(&ebt_mutex); 1148 list_del(&watcher->list); 1149 mutex_unlock(&ebt_mutex); 1150} 1151 1152int ebt_register_table(struct ebt_table *table) 1153{ 1154 struct ebt_table_info *newinfo; 1155 struct ebt_table *t; 1156 struct ebt_replace_kernel *repl; 1157 int ret, i, countersize; 1158 void *p; 1159 1160 if (!table || !(repl = table->table) || !repl->entries || 1161 repl->entries_size == 0 || 1162 repl->counters || table->private) { 1163 BUGPRINT("Bad table data for ebt_register_table!!!\n"); 1164 return -EINVAL; 1165 } 1166 1167 countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids; 1168 newinfo = vmalloc(sizeof(*newinfo) + countersize); 1169 ret = -ENOMEM; 1170 if (!newinfo) 1171 return -ENOMEM; 1172 1173 p = vmalloc(repl->entries_size); 1174 if (!p) 1175 goto free_newinfo; 1176 1177 memcpy(p, repl->entries, repl->entries_size); 1178 newinfo->entries = p; 1179 1180 newinfo->entries_size = repl->entries_size; 1181 newinfo->nentries = repl->nentries; 1182 1183 if (countersize) 1184 memset(newinfo->counters, 0, countersize); 1185 1186 /* fill in newinfo and parse the entries */ 1187 newinfo->chainstack = NULL; 1188 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 1189 if ((repl->valid_hooks & (1 << i)) == 0) 1190 newinfo->hook_entry[i] = NULL; 1191 else 1192 newinfo->hook_entry[i] = p + 1193 ((char *)repl->hook_entry[i] - repl->entries); 1194 } 1195 ret = translate_table(repl->name, newinfo); 1196 if (ret != 0) { 1197 BUGPRINT("Translate_table failed\n"); 1198 goto free_chainstack; 1199 } 1200 1201 if (table->check && table->check(newinfo, table->valid_hooks)) { 1202 BUGPRINT("The table doesn't like its own initial data, lol\n"); 1203 return -EINVAL; 1204 } 1205 1206 table->private = newinfo; 1207 rwlock_init(&table->lock); 1208 ret = mutex_lock_interruptible(&ebt_mutex); 1209 if (ret != 0) 1210 goto free_chainstack; 1211 1212 list_for_each_entry(t, &ebt_tables, list) { 1213 if (strcmp(t->name, table->name) == 0) { 1214 ret = -EEXIST; 1215 BUGPRINT("Table name already exists\n"); 1216 goto free_unlock; 1217 } 1218 } 1219 1220 /* Hold a reference count if the chains aren't empty */ 1221 if (newinfo->nentries && !try_module_get(table->me)) { 1222 ret = -ENOENT; 1223 goto free_unlock; 1224 } 1225 list_add(&table->list, &ebt_tables); 1226 mutex_unlock(&ebt_mutex); 1227 return 0; 1228free_unlock: 1229 mutex_unlock(&ebt_mutex); 1230free_chainstack: 1231 if (newinfo->chainstack) { 1232 for_each_possible_cpu(i) 1233 vfree(newinfo->chainstack[i]); 1234 vfree(newinfo->chainstack); 1235 } 1236 vfree(newinfo->entries); 1237free_newinfo: 1238 vfree(newinfo); 1239 return ret; 1240} 1241 1242void ebt_unregister_table(struct ebt_table *table) 1243{ 1244 int i; 1245 1246 if (!table) { 1247 BUGPRINT("Request to unregister NULL table!!!\n"); 1248 return; 1249 } 1250 mutex_lock(&ebt_mutex); 1251 list_del(&table->list); 1252 mutex_unlock(&ebt_mutex); 1253 vfree(table->private->entries); 1254 if (table->private->chainstack) { 1255 for_each_possible_cpu(i) 1256 vfree(table->private->chainstack[i]); 1257 vfree(table->private->chainstack); 1258 } 1259 vfree(table->private); 1260} 1261 1262/* userspace just supplied us with counters */ 1263static int update_counters(void __user *user, unsigned int len) 1264{ 1265 int i, ret; 1266 struct ebt_counter *tmp; 1267 struct ebt_replace hlp; 1268 struct ebt_table *t; 1269 1270 if (copy_from_user(&hlp, user, sizeof(hlp))) 1271 return -EFAULT; 1272 1273 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter)) 1274 return -EINVAL; 1275 if (hlp.num_counters == 0) 1276 return -EINVAL; 1277 1278 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) { 1279 MEMPRINT("Update_counters && nomemory\n"); 1280 return -ENOMEM; 1281 } 1282 1283 t = find_table_lock(hlp.name, &ret, &ebt_mutex); 1284 if (!t) 1285 goto free_tmp; 1286 1287 if (hlp.num_counters != t->private->nentries) { 1288 BUGPRINT("Wrong nr of counters\n"); 1289 ret = -EINVAL; 1290 goto unlock_mutex; 1291 } 1292 1293 if ( copy_from_user(tmp, hlp.counters, 1294 hlp.num_counters * sizeof(struct ebt_counter)) ) { 1295 BUGPRINT("Updata_counters && !cfu\n"); 1296 ret = -EFAULT; 1297 goto unlock_mutex; 1298 } 1299 1300 /* we want an atomic add of the counters */ 1301 write_lock_bh(&t->lock); 1302 1303 /* we add to the counters of the first cpu */ 1304 for (i = 0; i < hlp.num_counters; i++) { 1305 t->private->counters[i].pcnt += tmp[i].pcnt; 1306 t->private->counters[i].bcnt += tmp[i].bcnt; 1307 } 1308 1309 write_unlock_bh(&t->lock); 1310 ret = 0; 1311unlock_mutex: 1312 mutex_unlock(&ebt_mutex); 1313free_tmp: 1314 vfree(tmp); 1315 return ret; 1316} 1317 1318static inline int ebt_make_matchname(struct ebt_entry_match *m, 1319 char *base, char __user *ubase) 1320{ 1321 char __user *hlp = ubase + ((char *)m - base); 1322 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN)) 1323 return -EFAULT; 1324 return 0; 1325} 1326 1327static inline int ebt_make_watchername(struct ebt_entry_watcher *w, 1328 char *base, char __user *ubase) 1329{ 1330 char __user *hlp = ubase + ((char *)w - base); 1331 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN)) 1332 return -EFAULT; 1333 return 0; 1334} 1335 1336static inline int ebt_make_names(struct ebt_entry *e, char *base, char __user *ubase) 1337{ 1338 int ret; 1339 char __user *hlp; 1340 struct ebt_entry_target *t; 1341 1342 if (e->bitmask == 0) 1343 return 0; 1344 1345 hlp = ubase + (((char *)e + e->target_offset) - base); 1346 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 1347 1348 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase); 1349 if (ret != 0) 1350 return ret; 1351 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); 1352 if (ret != 0) 1353 return ret; 1354 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN)) 1355 return -EFAULT; 1356 return 0; 1357} 1358 1359/* called with ebt_mutex locked */ 1360static int copy_everything_to_user(struct ebt_table *t, void __user *user, 1361 int *len, int cmd) 1362{ 1363 struct ebt_replace tmp; 1364 struct ebt_counter *counterstmp, *oldcounters; 1365 unsigned int entries_size, nentries; 1366 char *entries; 1367 1368 if (cmd == EBT_SO_GET_ENTRIES) { 1369 entries_size = t->private->entries_size; 1370 nentries = t->private->nentries; 1371 entries = t->private->entries; 1372 oldcounters = t->private->counters; 1373 } else { 1374 entries_size = t->table->entries_size; 1375 nentries = t->table->nentries; 1376 entries = t->table->entries; 1377 oldcounters = t->table->counters; 1378 } 1379 1380 if (copy_from_user(&tmp, user, sizeof(tmp))) { 1381 BUGPRINT("Cfu didn't work\n"); 1382 return -EFAULT; 1383 } 1384 1385 if (*len != sizeof(struct ebt_replace) + entries_size + 1386 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) { 1387 BUGPRINT("Wrong size\n"); 1388 return -EINVAL; 1389 } 1390 1391 if (tmp.nentries != nentries) { 1392 BUGPRINT("Nentries wrong\n"); 1393 return -EINVAL; 1394 } 1395 1396 if (tmp.entries_size != entries_size) { 1397 BUGPRINT("Wrong size\n"); 1398 return -EINVAL; 1399 } 1400 1401 /* userspace might not need the counters */ 1402 if (tmp.num_counters) { 1403 if (tmp.num_counters != nentries) { 1404 BUGPRINT("Num_counters wrong\n"); 1405 return -EINVAL; 1406 } 1407 counterstmp = vmalloc(nentries * sizeof(*counterstmp)); 1408 if (!counterstmp) { 1409 MEMPRINT("Couldn't copy counters, out of memory\n"); 1410 return -ENOMEM; 1411 } 1412 write_lock_bh(&t->lock); 1413 get_counters(oldcounters, counterstmp, nentries); 1414 write_unlock_bh(&t->lock); 1415 1416 if (copy_to_user(tmp.counters, counterstmp, 1417 nentries * sizeof(struct ebt_counter))) { 1418 BUGPRINT("Couldn't copy counters to userspace\n"); 1419 vfree(counterstmp); 1420 return -EFAULT; 1421 } 1422 vfree(counterstmp); 1423 } 1424 1425 if (copy_to_user(tmp.entries, entries, entries_size)) { 1426 BUGPRINT("Couldn't copy entries to userspace\n"); 1427 return -EFAULT; 1428 } 1429 /* set the match/watcher/target names right */ 1430 return EBT_ENTRY_ITERATE(entries, entries_size, 1431 ebt_make_names, entries, tmp.entries); 1432} 1433 1434static int do_ebt_set_ctl(struct sock *sk, 1435 int cmd, void __user *user, unsigned int len) 1436{ 1437 int ret; 1438 1439 switch(cmd) { 1440 case EBT_SO_SET_ENTRIES: 1441 ret = do_replace(user, len); 1442 break; 1443 case EBT_SO_SET_COUNTERS: 1444 ret = update_counters(user, len); 1445 break; 1446 default: 1447 ret = -EINVAL; 1448 } 1449 return ret; 1450} 1451 1452static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) 1453{ 1454 int ret; 1455 struct ebt_replace tmp; 1456 struct ebt_table *t; 1457 1458 if (copy_from_user(&tmp, user, sizeof(tmp))) 1459 return -EFAULT; 1460 1461 t = find_table_lock(tmp.name, &ret, &ebt_mutex); 1462 if (!t) 1463 return ret; 1464 1465 switch(cmd) { 1466 case EBT_SO_GET_INFO: 1467 case EBT_SO_GET_INIT_INFO: 1468 if (*len != sizeof(struct ebt_replace)){ 1469 ret = -EINVAL; 1470 mutex_unlock(&ebt_mutex); 1471 break; 1472 } 1473 if (cmd == EBT_SO_GET_INFO) { 1474 tmp.nentries = t->private->nentries; 1475 tmp.entries_size = t->private->entries_size; 1476 tmp.valid_hooks = t->valid_hooks; 1477 } else { 1478 tmp.nentries = t->table->nentries; 1479 tmp.entries_size = t->table->entries_size; 1480 tmp.valid_hooks = t->table->valid_hooks; 1481 } 1482 mutex_unlock(&ebt_mutex); 1483 if (copy_to_user(user, &tmp, *len) != 0){ 1484 BUGPRINT("c2u Didn't work\n"); 1485 ret = -EFAULT; 1486 break; 1487 } 1488 ret = 0; 1489 break; 1490 1491 case EBT_SO_GET_ENTRIES: 1492 case EBT_SO_GET_INIT_ENTRIES: 1493 ret = copy_everything_to_user(t, user, len, cmd); 1494 mutex_unlock(&ebt_mutex); 1495 break; 1496 1497 default: 1498 mutex_unlock(&ebt_mutex); 1499 ret = -EINVAL; 1500 } 1501 1502 return ret; 1503} 1504 1505static struct nf_sockopt_ops ebt_sockopts = 1506{ 1507 .pf = PF_INET, 1508 .set_optmin = EBT_BASE_CTL, 1509 .set_optmax = EBT_SO_SET_MAX + 1, 1510 .set = do_ebt_set_ctl, 1511 .get_optmin = EBT_BASE_CTL, 1512 .get_optmax = EBT_SO_GET_MAX + 1, 1513 .get = do_ebt_get_ctl, 1514 .owner = THIS_MODULE, 1515}; 1516 1517static int __init ebtables_init(void) 1518{ 1519 int ret; 1520 1521 mutex_lock(&ebt_mutex); 1522 list_add(&ebt_standard_target.list, &ebt_targets); 1523 mutex_unlock(&ebt_mutex); 1524 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) 1525 return ret; 1526 1527 printk(KERN_INFO "Ebtables v2.0 registered\n"); 1528 return 0; 1529} 1530 1531static void __exit ebtables_fini(void) 1532{ 1533 nf_unregister_sockopt(&ebt_sockopts); 1534 printk(KERN_INFO "Ebtables v2.0 unregistered\n"); 1535} 1536 1537EXPORT_SYMBOL(ebt_register_table); 1538EXPORT_SYMBOL(ebt_unregister_table); 1539EXPORT_SYMBOL(ebt_register_match); 1540EXPORT_SYMBOL(ebt_unregister_match); 1541EXPORT_SYMBOL(ebt_register_watcher); 1542EXPORT_SYMBOL(ebt_unregister_watcher); 1543EXPORT_SYMBOL(ebt_register_target); 1544EXPORT_SYMBOL(ebt_unregister_target); 1545EXPORT_SYMBOL(ebt_do_table); 1546module_init(ebtables_init); 1547module_exit(ebtables_fini); 1548MODULE_LICENSE("GPL");