netfilter: ipset: 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.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>

authored by Jozsef Kadlecsik and committed by Patrick McHardy eafbd3fd 0e8a835a

+16 -2
+16 -2
net/netfilter/xt_set.c
··· 81 if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { 82 pr_warning("Protocol error: set match dimension " 83 "is over the limit!\n"); 84 return -ERANGE; 85 } 86 ··· 136 if (index == IPSET_INVALID_ID) { 137 pr_warning("Cannot find del_set index %u as target\n", 138 info->del_set.index); 139 return -ENOENT; 140 } 141 } ··· 145 info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { 146 pr_warning("Protocol error: SET target dimension " 147 "is over the limit!\n"); 148 return -ERANGE; 149 } 150 ··· 199 if (info->match_set.dim > IPSET_DIM_MAX) { 200 pr_warning("Protocol error: set match dimension " 201 "is over the limit!\n"); 202 return -ERANGE; 203 } 204 ··· 227 if (info->del_set.index != IPSET_INVALID_ID) 228 ip_set_del(info->del_set.index, 229 skb, par->family, 230 - info->add_set.dim, 231 info->del_set.flags); 232 233 return XT_CONTINUE; ··· 253 if (index == IPSET_INVALID_ID) { 254 pr_warning("Cannot find del_set index %u as target\n", 255 info->del_set.index); 256 return -ENOENT; 257 } 258 } 259 if (info->add_set.dim > IPSET_DIM_MAX || 260 - info->del_set.flags > IPSET_DIM_MAX) { 261 pr_warning("Protocol error: SET target dimension " 262 "is over the limit!\n"); 263 return -ERANGE; 264 } 265
··· 81 if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { 82 pr_warning("Protocol error: set match dimension " 83 "is over the limit!\n"); 84 + ip_set_nfnl_put(info->match_set.index); 85 return -ERANGE; 86 } 87 ··· 135 if (index == IPSET_INVALID_ID) { 136 pr_warning("Cannot find del_set index %u as target\n", 137 info->del_set.index); 138 + if (info->add_set.index != IPSET_INVALID_ID) 139 + ip_set_nfnl_put(info->add_set.index); 140 return -ENOENT; 141 } 142 } ··· 142 info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { 143 pr_warning("Protocol error: SET target dimension " 144 "is over the limit!\n"); 145 + if (info->add_set.index != IPSET_INVALID_ID) 146 + ip_set_nfnl_put(info->add_set.index); 147 + if (info->del_set.index != IPSET_INVALID_ID) 148 + ip_set_nfnl_put(info->del_set.index); 149 return -ERANGE; 150 } 151 ··· 192 if (info->match_set.dim > IPSET_DIM_MAX) { 193 pr_warning("Protocol error: set match dimension " 194 "is over the limit!\n"); 195 + ip_set_nfnl_put(info->match_set.index); 196 return -ERANGE; 197 } 198 ··· 219 if (info->del_set.index != IPSET_INVALID_ID) 220 ip_set_del(info->del_set.index, 221 skb, par->family, 222 + info->del_set.dim, 223 info->del_set.flags); 224 225 return XT_CONTINUE; ··· 245 if (index == IPSET_INVALID_ID) { 246 pr_warning("Cannot find del_set index %u as target\n", 247 info->del_set.index); 248 + if (info->add_set.index != IPSET_INVALID_ID) 249 + ip_set_nfnl_put(info->add_set.index); 250 return -ENOENT; 251 } 252 } 253 if (info->add_set.dim > IPSET_DIM_MAX || 254 + info->del_set.dim > IPSET_DIM_MAX) { 255 pr_warning("Protocol error: SET target dimension " 256 "is over the limit!\n"); 257 + if (info->add_set.index != IPSET_INVALID_ID) 258 + ip_set_nfnl_put(info->add_set.index); 259 + if (info->del_set.index != IPSET_INVALID_ID) 260 + ip_set_nfnl_put(info->del_set.index); 261 return -ERANGE; 262 } 263