|
@@ -603,14 +603,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i)
|
|
|
+static void cleanup_match(struct ip6t_entry_match *m, struct net *net)
|
|
|
{
|
|
|
struct xt_mtdtor_param par;
|
|
|
|
|
|
- if (i && (*i)-- == 0)
|
|
|
- return 1;
|
|
|
-
|
|
|
par.net = net;
|
|
|
par.match = m->u.kernel.match;
|
|
|
par.matchinfo = m->data;
|
|
@@ -618,7 +614,6 @@ cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i)
|
|
|
if (par.match->destroy != NULL)
|
|
|
par.match->destroy(&par);
|
|
|
module_put(par.match->me);
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -642,8 +637,7 @@ check_entry(const struct ip6t_entry *e, const char *name)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
|
|
|
- unsigned int *i)
|
|
|
+static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
|
|
|
{
|
|
|
const struct ip6t_ip6 *ipv6 = par->entryinfo;
|
|
|
int ret;
|
|
@@ -658,13 +652,11 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
|
|
|
par.match->name);
|
|
|
return ret;
|
|
|
}
|
|
|
- ++*i;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
|
|
|
- unsigned int *i)
|
|
|
+find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
|
|
|
{
|
|
|
struct xt_match *match;
|
|
|
int ret;
|
|
@@ -678,7 +670,7 @@ find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
|
|
|
}
|
|
|
m->u.kernel.match = match;
|
|
|
|
|
|
- ret = check_match(m, par, i);
|
|
|
+ ret = check_match(m, par);
|
|
|
if (ret)
|
|
|
goto err;
|
|
|
|
|
@@ -735,12 +727,11 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
|
|
|
mtpar.hook_mask = e->comefrom;
|
|
|
mtpar.family = NFPROTO_IPV6;
|
|
|
xt_ematch_foreach(ematch, e) {
|
|
|
- ret = find_check_match(ematch, &mtpar, &j);
|
|
|
+ ret = find_check_match(ematch, &mtpar);
|
|
|
if (ret != 0)
|
|
|
- break;
|
|
|
+ goto cleanup_matches;
|
|
|
+ ++j;
|
|
|
}
|
|
|
- if (ret != 0)
|
|
|
- goto cleanup_matches;
|
|
|
|
|
|
t = ip6t_get_target(e);
|
|
|
target = try_then_request_module(xt_find_target(AF_INET6,
|
|
@@ -761,9 +752,11 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
|
|
|
err:
|
|
|
module_put(t->u.kernel.target->me);
|
|
|
cleanup_matches:
|
|
|
- xt_ematch_foreach(ematch, e)
|
|
|
- if (cleanup_match(ematch, net, &j) != 0)
|
|
|
+ xt_ematch_foreach(ematch, e) {
|
|
|
+ if (j-- == 0)
|
|
|
break;
|
|
|
+ cleanup_match(ematch, net);
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -837,8 +830,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net)
|
|
|
|
|
|
/* Cleanup all matches */
|
|
|
xt_ematch_foreach(ematch, e)
|
|
|
- if (cleanup_match(ematch, net, NULL) != 0)
|
|
|
- break;
|
|
|
+ cleanup_match(ematch, net);
|
|
|
t = ip6t_get_target(e);
|
|
|
|
|
|
par.net = net;
|
|
@@ -1094,13 +1086,6 @@ static int compat_standard_to_user(void __user *dst, const void *src)
|
|
|
return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
|
|
|
}
|
|
|
|
|
|
-static inline int
|
|
|
-compat_calc_match(const struct ip6t_entry_match *m, int *size)
|
|
|
-{
|
|
|
- *size += xt_compat_match_offset(m->u.kernel.match);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int compat_calc_entry(const struct ip6t_entry *e,
|
|
|
const struct xt_table_info *info,
|
|
|
const void *base, struct xt_table_info *newinfo)
|
|
@@ -1113,8 +1098,7 @@ static int compat_calc_entry(const struct ip6t_entry *e,
|
|
|
off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
|
|
|
entry_offset = (void *)e - base;
|
|
|
xt_ematch_foreach(ematch, e)
|
|
|
- if (compat_calc_match(ematch, &off) != 0)
|
|
|
- break;
|
|
|
+ off += xt_compat_match_offset(ematch->u.kernel.match);
|
|
|
t = ip6t_get_target_c(e);
|
|
|
off += xt_compat_target_offset(t->u.kernel.target);
|
|
|
newinfo->size -= off;
|
|
@@ -1508,11 +1492,9 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
|
|
|
xt_ematch_foreach(ematch, e) {
|
|
|
ret = xt_compat_match_to_user(ematch, dstptr, size);
|
|
|
if (ret != 0)
|
|
|
- break;
|
|
|
+ return ret;
|
|
|
}
|
|
|
target_offset = e->target_offset - (origsize - *size);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
t = ip6t_get_target(e);
|
|
|
ret = xt_compat_target_to_user(t, dstptr, size);
|
|
|
if (ret)
|
|
@@ -1529,7 +1511,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
|
|
|
const char *name,
|
|
|
const struct ip6t_ip6 *ipv6,
|
|
|
unsigned int hookmask,
|
|
|
- int *size, unsigned int *i)
|
|
|
+ int *size)
|
|
|
{
|
|
|
struct xt_match *match;
|
|
|
|
|
@@ -1543,18 +1525,6 @@ compat_find_calc_match(struct ip6t_entry_match *m,
|
|
|
}
|
|
|
m->u.kernel.match = match;
|
|
|
*size += xt_compat_match_offset(match);
|
|
|
-
|
|
|
- (*i)++;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int
|
|
|
-compat_release_match(struct ip6t_entry_match *m, unsigned int *i)
|
|
|
-{
|
|
|
- if (i && (*i)-- == 0)
|
|
|
- return 1;
|
|
|
-
|
|
|
- module_put(m->u.kernel.match->me);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1565,8 +1535,7 @@ static void compat_release_entry(struct compat_ip6t_entry *e)
|
|
|
|
|
|
/* Cleanup all matches */
|
|
|
xt_ematch_foreach(ematch, e)
|
|
|
- if (compat_release_match(ematch, NULL) != 0)
|
|
|
- break;
|
|
|
+ module_put(ematch->u.kernel.match->me);
|
|
|
t = compat_ip6t_get_target(e);
|
|
|
module_put(t->u.kernel.target->me);
|
|
|
}
|
|
@@ -1612,12 +1581,11 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
|
|
|
j = 0;
|
|
|
xt_ematch_foreach(ematch, e) {
|
|
|
ret = compat_find_calc_match(ematch, name,
|
|
|
- &e->ipv6, e->comefrom, &off, &j);
|
|
|
+ &e->ipv6, e->comefrom, &off);
|
|
|
if (ret != 0)
|
|
|
- break;
|
|
|
+ goto release_matches;
|
|
|
+ ++j;
|
|
|
}
|
|
|
- if (ret != 0)
|
|
|
- goto release_matches;
|
|
|
|
|
|
t = compat_ip6t_get_target(e);
|
|
|
target = try_then_request_module(xt_find_target(AF_INET6,
|
|
@@ -1654,9 +1622,11 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
|
|
|
out:
|
|
|
module_put(t->u.kernel.target->me);
|
|
|
release_matches:
|
|
|
- xt_ematch_foreach(ematch, e)
|
|
|
- if (compat_release_match(ematch, &j) != 0)
|
|
|
+ xt_ematch_foreach(ematch, e) {
|
|
|
+ if (j-- == 0)
|
|
|
break;
|
|
|
+ module_put(ematch->u.kernel.match->me);
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1684,10 +1654,8 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
|
|
|
xt_ematch_foreach(ematch, e) {
|
|
|
ret = xt_compat_match_from_user(ematch, dstptr, size);
|
|
|
if (ret != 0)
|
|
|
- break;
|
|
|
+ return ret;
|
|
|
}
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
de->target_offset = e->target_offset - (origsize - *size);
|
|
|
t = compat_ip6t_get_target(e);
|
|
|
target = t->u.kernel.target;
|
|
@@ -1718,12 +1686,11 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,
|
|
|
mtpar.hook_mask = e->comefrom;
|
|
|
mtpar.family = NFPROTO_IPV6;
|
|
|
xt_ematch_foreach(ematch, e) {
|
|
|
- ret = check_match(ematch, &mtpar, &j);
|
|
|
+ ret = check_match(ematch, &mtpar);
|
|
|
if (ret != 0)
|
|
|
- break;
|
|
|
+ goto cleanup_matches;
|
|
|
+ ++j;
|
|
|
}
|
|
|
- if (ret)
|
|
|
- goto cleanup_matches;
|
|
|
|
|
|
ret = check_target(e, net, name);
|
|
|
if (ret)
|
|
@@ -1731,9 +1698,11 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,
|
|
|
return 0;
|
|
|
|
|
|
cleanup_matches:
|
|
|
- xt_ematch_foreach(ematch, e)
|
|
|
- if (cleanup_match(ematch, net, &j) != 0)
|
|
|
+ xt_ematch_foreach(ematch, e) {
|
|
|
+ if (j-- == 0)
|
|
|
break;
|
|
|
+ cleanup_match(ematch, net);
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|