]> Pileus Git - ~andy/linux/blobdiff - net/bridge/netfilter/ebtables.c
[NETFILTER]: ebtables: don't compute gap before checking struct type
[~andy/linux] / net / bridge / netfilter / ebtables.c
index 00a89705c1c4ec8eda7a613caaa8ff4d42ccb8a9..6c84ccb8c9d754d045bc6351812917f6cfbd3cb3 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;
                }
 
@@ -609,7 +610,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
        struct ebt_entry_target *t;
        struct ebt_target *target;
        unsigned int i, j, hook = 0, hookmask = 0;
-       size_t gap = e->next_offset - e->target_offset;
+       size_t gap;
        int ret;
 
        /* don't mess with the struct ebt_entries */
@@ -659,6 +660,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
        if (ret != 0)
                goto cleanup_watchers;
        t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
+       gap = e->next_offset - e->target_offset;
        target = find_target_lock(t->u.name, &ret, &ebt_mutex);
        if (!target)
                goto cleanup_watchers;
@@ -1156,7 +1158,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 +1322,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);