[EBTABLES]: Split ebt_replace into user and kernel variants, annotate.
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 1 Dec 2006 03:28:48 +0000 (19:28 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 3 Dec 2006 05:32:05 +0000 (21:32 -0800)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter_bridge/ebtables.h
net/bridge/netfilter/ebtable_broute.c
net/bridge/netfilter/ebtable_filter.c
net/bridge/netfilter/ebtable_nat.c
net/bridge/netfilter/ebtables.c

index 87775264ff0bea1b1065a5145bc8e7180f8842f9..94e0a7dc0cb251bee343cf22442068fdf8553cec 100644 (file)
@@ -38,6 +38,23 @@ struct ebt_counter
 };
 
 struct ebt_replace
+{
+       char name[EBT_TABLE_MAXNAMELEN];
+       unsigned int valid_hooks;
+       /* nr of rules in the table */
+       unsigned int nentries;
+       /* total size of the entries */
+       unsigned int entries_size;
+       /* start of the chains */
+       struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS];
+       /* nr of counters userspace expects back */
+       unsigned int num_counters;
+       /* where the kernel will put the old counters */
+       struct ebt_counter __user *counters;
+       char __user *entries;
+};
+
+struct ebt_replace_kernel
 {
        char name[EBT_TABLE_MAXNAMELEN];
        unsigned int valid_hooks;
@@ -255,7 +272,7 @@ struct ebt_table
 {
        struct list_head list;
        char name[EBT_TABLE_MAXNAMELEN];
-       struct ebt_replace *table;
+       struct ebt_replace_kernel *table;
        unsigned int valid_hooks;
        rwlock_t lock;
        /* e.g. could be the table explicitly only allows certain
index 9a6e548e148b2340cc910be1dc1a6c1284701129..d37ce04789388028b2b8a56803c2e17658fc42c4 100644 (file)
@@ -23,7 +23,7 @@ static struct ebt_entries initial_chain = {
        .policy         = EBT_ACCEPT,
 };
 
-static struct ebt_replace initial_table =
+static struct ebt_replace_kernel initial_table =
 {
        .name           = "broute",
        .valid_hooks    = 1 << NF_BR_BROUTING,
index 3d5bd44f23955bac7066841c0000a01a0082cf1d..127135ead2d5ade31f30571425fd15085e0920cf 100644 (file)
@@ -30,7 +30,7 @@ static struct ebt_entries initial_chains[] =
        },
 };
 
-static struct ebt_replace initial_table =
+static struct ebt_replace_kernel initial_table =
 {
        .name           = "filter",
        .valid_hooks    = FILTER_VALID_HOOKS,
index 04dd42efda1d337ba2610c049c2b7870fa7e4da8..9c50488b62ebe84c07e2a27b32d3b016efd67cc5 100644 (file)
@@ -30,7 +30,7 @@ static struct ebt_entries initial_chains[] =
        }
 };
 
-static struct ebt_replace initial_table =
+static struct ebt_replace_kernel initial_table =
 {
        .name           = "nat",
        .valid_hooks    = NAT_VALID_HOOKS,
index 00a89705c1c4ec8eda7a613caaa8ff4d42ccb8a9..bee558a41800e2700a4f00e84e06224f57d368b0 100644 (file)
@@ -417,7 +417,8 @@ static int ebt_verify_pointers(struct ebt_replace *repl,
                for (i = 0; i < NF_BR_NUMHOOKS; i++) {
                        if ((valid_hooks & (1 << i)) == 0)
                                continue;
-                       if ((char *)repl->hook_entry[i] == repl->entries + offset)
+                       if ((char __user *)repl->hook_entry[i] ==
+                            repl->entries + offset)
                                break;
                }
 
@@ -1156,7 +1157,7 @@ int ebt_register_table(struct ebt_table *table)
 {
        struct ebt_table_info *newinfo;
        struct ebt_table *t;
-       struct ebt_replace *repl;
+       struct ebt_replace_kernel *repl;
        int ret, i, countersize;
        void *p;
 
@@ -1320,33 +1321,33 @@ free_tmp:
 }
 
 static inline int ebt_make_matchname(struct ebt_entry_match *m,
-   char *base, char *ubase)
+   char *base, char __user *ubase)
 {
-       char *hlp = ubase - base + (char *)m;
+       char __user *hlp = ubase + ((char *)m - base);
        if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
                return -EFAULT;
        return 0;
 }
 
 static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
-   char *base, char *ubase)
+   char *base, char __user *ubase)
 {
-       char *hlp = ubase - base + (char *)w;
+       char __user *hlp = ubase + ((char *)w - base);
        if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
                return -EFAULT;
        return 0;
 }
 
-static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
+static inline int ebt_make_names(struct ebt_entry *e, char *base, char __user *ubase)
 {
        int ret;
-       char *hlp;
+       char __user *hlp;
        struct ebt_entry_target *t;
 
        if (e->bitmask == 0)
                return 0;
 
-       hlp = ubase - base + (char *)e + e->target_offset;
+       hlp = ubase + (((char *)e + e->target_offset) - base);
        t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
        
        ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);