return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
+               return -EINVAL;
+
        t = arpt_get_target(e);
+       if (e->target_offset + t->u.target_size > e->next_offset)
+               return -EINVAL;
+
        target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
                                                        t->u.user.revision),
                                         "arpt_%s", t->u.user.name);
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
-               duprintf("Looping hook\n");
-               return -ELOOP;
-       }
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
                                 check_entry, name, size, &i);
 
-       if (ret != 0) {
-               ARPT_ENTRY_ITERATE(entry0, newinfo->size,
-                                  cleanup_entry, &i);
-               return ret;
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
+               duprintf("Looping hook\n");
+               goto cleanup;
        }
 
        /* And one copy for every other CPU */
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }
 
 
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
+               return -EINVAL;
+
        j = 0;
        ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ipt_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET,
                                                     t->u.user.name,
                                                     t->u.user.revision),
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0))
-               return -ELOOP;
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
-       if (ret != 0) {
-               IPT_ENTRY_ITERATE(entry0, newinfo->size,
-                                 cleanup_entry, &i);
-               return ret;
-       }
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
+               goto cleanup;
 
        /* And one copy for every other CPU */
        for_each_possible_cpu(i) {
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }
 
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct compat_xt_entry_target) >
+                                                               e->next_offset)
+               return -EINVAL;
+
        off = 0;
        entry_offset = (void *)e - (void *)base;
        j = 0;
                goto cleanup_matches;
 
        t = ipt_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET,
                                                     t->u.user.name,
                                                     t->u.user.revision),
 
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct ip6t_entry_target) >
+                                                               e->next_offset)
+               return -EINVAL;
+
        j = 0;
        ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ip6t_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET6,
                                                        t->u.user.name,
                                                        t->u.user.revision),
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0))
-               return -ELOOP;
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
-       if (ret != 0) {
-               IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                                 cleanup_entry, &i);
-               return ret;
-       }
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
+               goto cleanup;
 
        /* And one copy for every other CPU */
        for_each_possible_cpu(i) {
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }