summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-09 21:35:02 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-09 21:35:02 +0200
commit1e4221aa032195b328e7cecf67875fa39b69e1ee (patch)
tree499865e97237352174e72fbfb2e2b5fe928bcac6 /kernel
parent6787a0c52d775660ec052571c8a91b3804dc8e52 (diff)
set match and SET target fixes
The SET target with --del-set did not work due to using wrongly the internal dimension of --add-set instead of --del-set. Also, the checkentries did not release the set references when returned an error. Bugs reported by Lennert Buytenhek.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/net/netfilter/xt_set.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/kernel/net/netfilter/xt_set.c b/kernel/net/netfilter/xt_set.c
index 4930839..581079d 100644
--- a/kernel/net/netfilter/xt_set.c
+++ b/kernel/net/netfilter/xt_set.c
@@ -115,6 +115,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
pr_warning("Protocol error: set match dimension "
"is over the limit!\n");
+ ip_set_nfnl_put(info->match_set.index);
return CHECK_FAIL(-ERANGE); /* error */
}
@@ -179,6 +180,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
if (index == IPSET_INVALID_ID) {
pr_warning("Cannot find del_set index %u as target\n",
info->del_set.index);
+ if (info->add_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->add_set.index);
return CHECK_FAIL(-ENOENT); /* error */
}
}
@@ -186,6 +189,10 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
pr_warning("Protocol error: SET target dimension "
"is over the limit!\n");
+ if (info->add_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->add_set.index);
+ if (info->del_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->del_set.index);
return CHECK_FAIL(-ERANGE); /* error */
}
@@ -246,6 +253,7 @@ set_match_checkentry(const struct xt_mtchk_param *par)
if (info->match_set.dim > IPSET_DIM_MAX) {
pr_warning("Protocol error: set match dimension "
"is over the limit!\n");
+ ip_set_nfnl_put(info->match_set.index);
return CHECK_FAIL(-ERANGE); /* error */
}
@@ -278,7 +286,7 @@ set_target(struct sk_buff *skb, const struct xt_action_param *par)
if (info->del_set.index != IPSET_INVALID_ID)
ip_set_del(info->del_set.index,
skb, par->family,
- info->add_set.dim,
+ info->del_set.dim,
info->del_set.flags);
return XT_CONTINUE;
@@ -309,13 +317,19 @@ set_target_checkentry(const struct xt_tgchk_param *par)
if (index == IPSET_INVALID_ID) {
pr_warning("Cannot find del_set index %u as target\n",
info->del_set.index);
+ if (info->add_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->add_set.index);
return CHECK_FAIL(-ENOENT); /* error */
}
}
if (info->add_set.dim > IPSET_DIM_MAX ||
- info->del_set.flags > IPSET_DIM_MAX) {
+ info->del_set.dim > IPSET_DIM_MAX) {
pr_warning("Protocol error: SET target dimension "
"is over the limit!\n");
+ if (info->add_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->add_set.index);
+ if (info->del_set.index != IPSET_INVALID_ID)
+ ip_set_nfnl_put(info->del_set.index);
return CHECK_FAIL(-ERANGE); /* error */
}