linux/net/bridge/netfilter/ebtables.c
<<
>>
Prefs
   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        tmp.name[sizeof(tmp.name) - 1] = 0;
 948
 949        countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
 950        newinfo = vmalloc(sizeof(*newinfo) + countersize);
 951        if (!newinfo)
 952                return -ENOMEM;
 953
 954        if (countersize)
 955                memset(newinfo->counters, 0, countersize);
 956
 957        newinfo->entries = vmalloc(tmp.entries_size);
 958        if (!newinfo->entries) {
 959                ret = -ENOMEM;
 960                goto free_newinfo;
 961        }
 962        if (copy_from_user(
 963           newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
 964                BUGPRINT("Couldn't copy entries from userspace\n");
 965                ret = -EFAULT;
 966                goto free_entries;
 967        }
 968
 969        /* the user wants counters back
 970           the check on the size is done later, when we have the lock */
 971        if (tmp.num_counters) {
 972                counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
 973                if (!counterstmp) {
 974                        ret = -ENOMEM;
 975                        goto free_entries;
 976                }
 977        }
 978        else
 979                counterstmp = NULL;
 980
 981        /* this can get initialized by translate_table() */
 982        newinfo->chainstack = NULL;
 983        ret = ebt_verify_pointers(&tmp, newinfo);
 984        if (ret != 0)
 985                goto free_counterstmp;
 986
 987        ret = translate_table(tmp.name, newinfo);
 988
 989        if (ret != 0)
 990                goto free_counterstmp;
 991
 992        t = find_table_lock(tmp.name, &ret, &ebt_mutex);
 993        if (!t) {
 994                ret = -ENOENT;
 995                goto free_iterate;
 996        }
 997
 998        /* the table doesn't like it */
 999        if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
1000                goto free_unlock;
1001
1002        if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
1003                BUGPRINT("Wrong nr. of counters requested\n");
1004                ret = -EINVAL;
1005                goto free_unlock;
1006        }
1007
1008        /* we have the mutex lock, so no danger in reading this pointer */
1009        table = t->private;
1010        /* make sure the table can only be rmmod'ed if it contains no rules */
1011        if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1012                ret = -ENOENT;
1013                goto free_unlock;
1014        } else if (table->nentries && !newinfo->nentries)
1015                module_put(t->me);
1016        /* we need an atomic snapshot of the counters */
1017        write_lock_bh(&t->lock);
1018        if (tmp.num_counters)
1019                get_counters(t->private->counters, counterstmp,
1020                   t->private->nentries);
1021
1022        t->private = newinfo;
1023        write_unlock_bh(&t->lock);
1024        mutex_unlock(&ebt_mutex);
1025        /* so, a user can change the chains while having messed up her counter
1026           allocation. Only reason why this is done is because this way the lock
1027           is held only once, while this doesn't bring the kernel into a
1028           dangerous state. */
1029        if (tmp.num_counters &&
1030           copy_to_user(tmp.counters, counterstmp,
1031           tmp.num_counters * sizeof(struct ebt_counter))) {
1032                BUGPRINT("Couldn't copy counters to userspace\n");
1033                ret = -EFAULT;
1034        }
1035        else
1036                ret = 0;
1037
1038        /* decrease module count and free resources */
1039        EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1040           ebt_cleanup_entry, NULL);
1041
1042        vfree(table->entries);
1043        if (table->chainstack) {
1044                for_each_possible_cpu(i)
1045                        vfree(table->chainstack[i]);
1046                vfree(table->chainstack);
1047        }
1048        vfree(table);
1049
1050        vfree(counterstmp);
1051        return ret;
1052
1053free_unlock:
1054        mutex_unlock(&ebt_mutex);
1055free_iterate:
1056        EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1057           ebt_cleanup_entry, NULL);
1058free_counterstmp:
1059        vfree(counterstmp);
1060        /* can be initialized in translate_table() */
1061        if (newinfo->chainstack) {
1062                for_each_possible_cpu(i)
1063                        vfree(newinfo->chainstack[i]);
1064                vfree(newinfo->chainstack);
1065        }
1066free_entries:
1067        vfree(newinfo->entries);
1068free_newinfo:
1069        vfree(newinfo);
1070        return ret;
1071}
1072
1073int ebt_register_target(struct ebt_target *target)
1074{
1075        struct ebt_target *t;
1076        int ret;
1077
1078        ret = mutex_lock_interruptible(&ebt_mutex);
1079        if (ret != 0)
1080                return ret;
1081        list_for_each_entry(t, &ebt_targets, list) {
1082                if (strcmp(t->name, target->name) == 0) {
1083                        mutex_unlock(&ebt_mutex);
1084                        return -EEXIST;
1085                }
1086        }
1087        list_add(&target->list, &ebt_targets);
1088        mutex_unlock(&ebt_mutex);
1089
1090        return 0;
1091}
1092
1093void ebt_unregister_target(struct ebt_target *target)
1094{
1095        mutex_lock(&ebt_mutex);
1096        list_del(&target->list);
1097        mutex_unlock(&ebt_mutex);
1098}
1099
1100int ebt_register_match(struct ebt_match *match)
1101{
1102        struct ebt_match *m;
1103        int ret;
1104
1105        ret = mutex_lock_interruptible(&ebt_mutex);
1106        if (ret != 0)
1107                return ret;
1108        list_for_each_entry(m, &ebt_matches, list) {
1109                if (strcmp(m->name, match->name) == 0) {
1110                        mutex_unlock(&ebt_mutex);
1111                        return -EEXIST;
1112                }
1113        }
1114        list_add(&match->list, &ebt_matches);
1115        mutex_unlock(&ebt_mutex);
1116
1117        return 0;
1118}
1119
1120void ebt_unregister_match(struct ebt_match *match)
1121{
1122        mutex_lock(&ebt_mutex);
1123        list_del(&match->list);
1124        mutex_unlock(&ebt_mutex);
1125}
1126
1127int ebt_register_watcher(struct ebt_watcher *watcher)
1128{
1129        struct ebt_watcher *w;
1130        int ret;
1131
1132        ret = mutex_lock_interruptible(&ebt_mutex);
1133        if (ret != 0)
1134                return ret;
1135        list_for_each_entry(w, &ebt_watchers, list) {
1136                if (strcmp(w->name, watcher->name) == 0) {
1137                        mutex_unlock(&ebt_mutex);
1138                        return -EEXIST;
1139                }
1140        }
1141        list_add(&watcher->list, &ebt_watchers);
1142        mutex_unlock(&ebt_mutex);
1143
1144        return 0;
1145}
1146
1147void ebt_unregister_watcher(struct ebt_watcher *watcher)
1148{
1149        mutex_lock(&ebt_mutex);
1150        list_del(&watcher->list);
1151        mutex_unlock(&ebt_mutex);
1152}
1153
1154int ebt_register_table(struct ebt_table *table)
1155{
1156        struct ebt_table_info *newinfo;
1157        struct ebt_table *t;
1158        struct ebt_replace_kernel *repl;
1159        int ret, i, countersize;
1160        void *p;
1161
1162        if (!table || !(repl = table->table) || !repl->entries ||
1163            repl->entries_size == 0 ||
1164            repl->counters || table->private) {
1165                BUGPRINT("Bad table data for ebt_register_table!!!\n");
1166                return -EINVAL;
1167        }
1168
1169        countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids;
1170        newinfo = vmalloc(sizeof(*newinfo) + countersize);
1171        ret = -ENOMEM;
1172        if (!newinfo)
1173                return -ENOMEM;
1174
1175        p = vmalloc(repl->entries_size);
1176        if (!p)
1177                goto free_newinfo;
1178
1179        memcpy(p, repl->entries, repl->entries_size);
1180        newinfo->entries = p;
1181
1182        newinfo->entries_size = repl->entries_size;
1183        newinfo->nentries = repl->nentries;
1184
1185        if (countersize)
1186                memset(newinfo->counters, 0, countersize);
1187
1188        /* fill in newinfo and parse the entries */
1189        newinfo->chainstack = NULL;
1190        for (i = 0; i < NF_BR_NUMHOOKS; i++) {
1191                if ((repl->valid_hooks & (1 << i)) == 0)
1192                        newinfo->hook_entry[i] = NULL;
1193                else
1194                        newinfo->hook_entry[i] = p +
1195                                ((char *)repl->hook_entry[i] - repl->entries);
1196        }
1197        ret = translate_table(repl->name, newinfo);
1198        if (ret != 0) {
1199                BUGPRINT("Translate_table failed\n");
1200                goto free_chainstack;
1201        }
1202
1203        if (table->check && table->check(newinfo, table->valid_hooks)) {
1204                BUGPRINT("The table doesn't like its own initial data, lol\n");
1205                return -EINVAL;
1206        }
1207
1208        table->private = newinfo;
1209        rwlock_init(&table->lock);
1210        ret = mutex_lock_interruptible(&ebt_mutex);
1211        if (ret != 0)
1212                goto free_chainstack;
1213
1214        list_for_each_entry(t, &ebt_tables, list) {
1215                if (strcmp(t->name, table->name) == 0) {
1216                        ret = -EEXIST;
1217                        BUGPRINT("Table name already exists\n");
1218                        goto free_unlock;
1219                }
1220        }
1221
1222        /* Hold a reference count if the chains aren't empty */
1223        if (newinfo->nentries && !try_module_get(table->me)) {
1224                ret = -ENOENT;
1225                goto free_unlock;
1226        }
1227        list_add(&table->list, &ebt_tables);
1228        mutex_unlock(&ebt_mutex);
1229        return 0;
1230free_unlock:
1231        mutex_unlock(&ebt_mutex);
1232free_chainstack:
1233        if (newinfo->chainstack) {
1234                for_each_possible_cpu(i)
1235                        vfree(newinfo->chainstack[i]);
1236                vfree(newinfo->chainstack);
1237        }
1238        vfree(newinfo->entries);
1239free_newinfo:
1240        vfree(newinfo);
1241        return ret;
1242}
1243
1244void ebt_unregister_table(struct ebt_table *table)
1245{
1246        int i;
1247
1248        if (!table) {
1249                BUGPRINT("Request to unregister NULL table!!!\n");
1250                return;
1251        }
1252        mutex_lock(&ebt_mutex);
1253        list_del(&table->list);
1254        mutex_unlock(&ebt_mutex);
1255        vfree(table->private->entries);
1256        if (table->private->chainstack) {
1257                for_each_possible_cpu(i)
1258                        vfree(table->private->chainstack[i]);
1259                vfree(table->private->chainstack);
1260        }
1261        vfree(table->private);
1262}
1263
1264/* userspace just supplied us with counters */
1265static int update_counters(void __user *user, unsigned int len)
1266{
1267        int i, ret;
1268        struct ebt_counter *tmp;
1269        struct ebt_replace hlp;
1270        struct ebt_table *t;
1271
1272        if (copy_from_user(&hlp, user, sizeof(hlp)))
1273                return -EFAULT;
1274
1275        if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1276                return -EINVAL;
1277        if (hlp.num_counters == 0)
1278                return -EINVAL;
1279
1280        if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
1281                MEMPRINT("Update_counters && nomemory\n");
1282                return -ENOMEM;
1283        }
1284
1285        t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1286        if (!t)
1287                goto free_tmp;
1288
1289        if (hlp.num_counters != t->private->nentries) {
1290                BUGPRINT("Wrong nr of counters\n");
1291                ret = -EINVAL;
1292                goto unlock_mutex;
1293        }
1294
1295        if ( copy_from_user(tmp, hlp.counters,
1296           hlp.num_counters * sizeof(struct ebt_counter)) ) {
1297                BUGPRINT("Updata_counters && !cfu\n");
1298                ret = -EFAULT;
1299                goto unlock_mutex;
1300        }
1301
1302        /* we want an atomic add of the counters */
1303        write_lock_bh(&t->lock);
1304
1305        /* we add to the counters of the first cpu */
1306        for (i = 0; i < hlp.num_counters; i++) {
1307                t->private->counters[i].pcnt += tmp[i].pcnt;
1308                t->private->counters[i].bcnt += tmp[i].bcnt;
1309        }
1310
1311        write_unlock_bh(&t->lock);
1312        ret = 0;
1313unlock_mutex:
1314        mutex_unlock(&ebt_mutex);
1315free_tmp:
1316        vfree(tmp);
1317        return ret;
1318}
1319
1320static inline int ebt_make_matchname(struct ebt_entry_match *m,
1321   char *base, char __user *ubase)
1322{
1323        char __user *hlp = ubase + ((char *)m - base);
1324        if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1325                return -EFAULT;
1326        return 0;
1327}
1328
1329static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1330   char *base, char __user *ubase)
1331{
1332        char __user *hlp = ubase + ((char *)w - base);
1333        if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1334                return -EFAULT;
1335        return 0;
1336}
1337
1338static inline int ebt_make_names(struct ebt_entry *e, char *base, char __user *ubase)
1339{
1340        int ret;
1341        char __user *hlp;
1342        struct ebt_entry_target *t;
1343
1344        if (e->bitmask == 0)
1345                return 0;
1346
1347        hlp = ubase + (((char *)e + e->target_offset) - base);
1348        t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1349
1350        ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1351        if (ret != 0)
1352                return ret;
1353        ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1354        if (ret != 0)
1355                return ret;
1356        if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1357                return -EFAULT;
1358        return 0;
1359}
1360
1361/* called with ebt_mutex locked */
1362static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1363   int *len, int cmd)
1364{
1365        struct ebt_replace tmp;
1366        struct ebt_counter *counterstmp, *oldcounters;
1367        unsigned int entries_size, nentries;
1368        char *entries;
1369
1370        if (cmd == EBT_SO_GET_ENTRIES) {
1371                entries_size = t->private->entries_size;
1372                nentries = t->private->nentries;
1373                entries = t->private->entries;
1374                oldcounters = t->private->counters;
1375        } else {
1376                entries_size = t->table->entries_size;
1377                nentries = t->table->nentries;
1378                entries = t->table->entries;
1379                oldcounters = t->table->counters;
1380        }
1381
1382        if (copy_from_user(&tmp, user, sizeof(tmp))) {
1383                BUGPRINT("Cfu didn't work\n");
1384                return -EFAULT;
1385        }
1386
1387        if (*len != sizeof(struct ebt_replace) + entries_size +
1388           (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1389                BUGPRINT("Wrong size\n");
1390                return -EINVAL;
1391        }
1392
1393        if (tmp.nentries != nentries) {
1394                BUGPRINT("Nentries wrong\n");
1395                return -EINVAL;
1396        }
1397
1398        if (tmp.entries_size != entries_size) {
1399                BUGPRINT("Wrong size\n");
1400                return -EINVAL;
1401        }
1402
1403        /* userspace might not need the counters */
1404        if (tmp.num_counters) {
1405                if (tmp.num_counters != nentries) {
1406                        BUGPRINT("Num_counters wrong\n");
1407                        return -EINVAL;
1408                }
1409                counterstmp = vmalloc(nentries * sizeof(*counterstmp));
1410                if (!counterstmp) {
1411                        MEMPRINT("Couldn't copy counters, out of memory\n");
1412                        return -ENOMEM;
1413                }
1414                write_lock_bh(&t->lock);
1415                get_counters(oldcounters, counterstmp, nentries);
1416                write_unlock_bh(&t->lock);
1417
1418                if (copy_to_user(tmp.counters, counterstmp,
1419                   nentries * sizeof(struct ebt_counter))) {
1420                        BUGPRINT("Couldn't copy counters to userspace\n");
1421                        vfree(counterstmp);
1422                        return -EFAULT;
1423                }
1424                vfree(counterstmp);
1425        }
1426
1427        if (copy_to_user(tmp.entries, entries, entries_size)) {
1428                BUGPRINT("Couldn't copy entries to userspace\n");
1429                return -EFAULT;
1430        }
1431        /* set the match/watcher/target names right */
1432        return EBT_ENTRY_ITERATE(entries, entries_size,
1433           ebt_make_names, entries, tmp.entries);
1434}
1435
1436static int do_ebt_set_ctl(struct sock *sk,
1437        int cmd, void __user *user, unsigned int len)
1438{
1439        int ret;
1440
1441        if (!capable(CAP_NET_ADMIN))
1442                return -EPERM;
1443
1444        switch(cmd) {
1445        case EBT_SO_SET_ENTRIES:
1446                ret = do_replace(user, len);
1447                break;
1448        case EBT_SO_SET_COUNTERS:
1449                ret = update_counters(user, len);
1450                break;
1451        default:
1452                ret = -EINVAL;
1453  }
1454        return ret;
1455}
1456
1457static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1458{
1459        int ret;
1460        struct ebt_replace tmp;
1461        struct ebt_table *t;
1462
1463        if (!capable(CAP_NET_ADMIN))
1464                return -EPERM;
1465
1466        if (copy_from_user(&tmp, user, sizeof(tmp)))
1467                return -EFAULT;
1468
1469        t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1470        if (!t)
1471                return ret;
1472
1473        switch(cmd) {
1474        case EBT_SO_GET_INFO:
1475        case EBT_SO_GET_INIT_INFO:
1476                if (*len != sizeof(struct ebt_replace)){
1477                        ret = -EINVAL;
1478                        mutex_unlock(&ebt_mutex);
1479                        break;
1480                }
1481                if (cmd == EBT_SO_GET_INFO) {
1482                        tmp.nentries = t->private->nentries;
1483                        tmp.entries_size = t->private->entries_size;
1484                        tmp.valid_hooks = t->valid_hooks;
1485                } else {
1486                        tmp.nentries = t->table->nentries;
1487                        tmp.entries_size = t->table->entries_size;
1488                        tmp.valid_hooks = t->table->valid_hooks;
1489                }
1490                mutex_unlock(&ebt_mutex);
1491                if (copy_to_user(user, &tmp, *len) != 0){
1492                        BUGPRINT("c2u Didn't work\n");
1493                        ret = -EFAULT;
1494                        break;
1495                }
1496                ret = 0;
1497                break;
1498
1499        case EBT_SO_GET_ENTRIES:
1500        case EBT_SO_GET_INIT_ENTRIES:
1501                ret = copy_everything_to_user(t, user, len, cmd);
1502                mutex_unlock(&ebt_mutex);
1503                break;
1504
1505        default:
1506                mutex_unlock(&ebt_mutex);
1507                ret = -EINVAL;
1508        }
1509
1510        return ret;
1511}
1512
1513static struct nf_sockopt_ops ebt_sockopts =
1514{
1515        .pf             = PF_INET,
1516        .set_optmin     = EBT_BASE_CTL,
1517        .set_optmax     = EBT_SO_SET_MAX + 1,
1518        .set            = do_ebt_set_ctl,
1519        .get_optmin     = EBT_BASE_CTL,
1520        .get_optmax     = EBT_SO_GET_MAX + 1,
1521        .get            = do_ebt_get_ctl,
1522        .owner          = THIS_MODULE,
1523};
1524
1525static int __init ebtables_init(void)
1526{
1527        int ret;
1528
1529        mutex_lock(&ebt_mutex);
1530        list_add(&ebt_standard_target.list, &ebt_targets);
1531        mutex_unlock(&ebt_mutex);
1532        if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1533                return ret;
1534
1535        printk(KERN_INFO "Ebtables v2.0 registered\n");
1536        return 0;
1537}
1538
1539static void __exit ebtables_fini(void)
1540{
1541        nf_unregister_sockopt(&ebt_sockopts);
1542        printk(KERN_INFO "Ebtables v2.0 unregistered\n");
1543}
1544
1545EXPORT_SYMBOL(ebt_register_table);
1546EXPORT_SYMBOL(ebt_unregister_table);
1547EXPORT_SYMBOL(ebt_register_match);
1548EXPORT_SYMBOL(ebt_unregister_match);
1549EXPORT_SYMBOL(ebt_register_watcher);
1550EXPORT_SYMBOL(ebt_unregister_watcher);
1551EXPORT_SYMBOL(ebt_register_target);
1552EXPORT_SYMBOL(ebt_unregister_target);
1553EXPORT_SYMBOL(ebt_do_table);
1554module_init(ebtables_init);
1555module_exit(ebtables_fini);
1556MODULE_LICENSE("GPL");
1557
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.