diff options
author | Patrick McHardy <kaber@trash.net> | 2006-08-13 21:57:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-08-13 21:57:28 -0400 |
commit | 0eff66e625306a794ecba4b29ed12f7a147ce219 (patch) | |
tree | 2f6cfe4d4c6305ccf1c0e942865e8753959a27a4 /net | |
parent | 7ee66fcb94cb8be77d5f34cce7d315d11759f9c1 (diff) |
[NETFILTER]: {arp,ip,ip6}_tables: proper error recovery in init path
Neither of {arp,ip,ip6}_tables cleans up behind itself when something goes
wrong during initialization.
Noticed by Rennie deGraaf <degraaf@cpsc.ucalgary.ca>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 27 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 33 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 34 |
3 files changed, 70 insertions, 24 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 80c73ca90116..df4854cf598b 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -1170,21 +1170,34 @@ static int __init arp_tables_init(void) | |||
1170 | { | 1170 | { |
1171 | int ret; | 1171 | int ret; |
1172 | 1172 | ||
1173 | xt_proto_init(NF_ARP); | 1173 | ret = xt_proto_init(NF_ARP); |
1174 | if (ret < 0) | ||
1175 | goto err1; | ||
1174 | 1176 | ||
1175 | /* Noone else will be downing sem now, so we won't sleep */ | 1177 | /* Noone else will be downing sem now, so we won't sleep */ |
1176 | xt_register_target(&arpt_standard_target); | 1178 | ret = xt_register_target(&arpt_standard_target); |
1177 | xt_register_target(&arpt_error_target); | 1179 | if (ret < 0) |
1180 | goto err2; | ||
1181 | ret = xt_register_target(&arpt_error_target); | ||
1182 | if (ret < 0) | ||
1183 | goto err3; | ||
1178 | 1184 | ||
1179 | /* Register setsockopt */ | 1185 | /* Register setsockopt */ |
1180 | ret = nf_register_sockopt(&arpt_sockopts); | 1186 | ret = nf_register_sockopt(&arpt_sockopts); |
1181 | if (ret < 0) { | 1187 | if (ret < 0) |
1182 | duprintf("Unable to register sockopts.\n"); | 1188 | goto err4; |
1183 | return ret; | ||
1184 | } | ||
1185 | 1189 | ||
1186 | printk("arp_tables: (C) 2002 David S. Miller\n"); | 1190 | printk("arp_tables: (C) 2002 David S. Miller\n"); |
1187 | return 0; | 1191 | return 0; |
1192 | |||
1193 | err4: | ||
1194 | xt_unregister_target(&arpt_error_target); | ||
1195 | err3: | ||
1196 | xt_unregister_target(&arpt_standard_target); | ||
1197 | err2: | ||
1198 | xt_proto_fini(NF_ARP); | ||
1199 | err1: | ||
1200 | return ret; | ||
1188 | } | 1201 | } |
1189 | 1202 | ||
1190 | static void __exit arp_tables_fini(void) | 1203 | static void __exit arp_tables_fini(void) |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index fc5bdd5eb7d3..f316ff5fd8a6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -2239,22 +2239,39 @@ static int __init ip_tables_init(void) | |||
2239 | { | 2239 | { |
2240 | int ret; | 2240 | int ret; |
2241 | 2241 | ||
2242 | xt_proto_init(AF_INET); | 2242 | ret = xt_proto_init(AF_INET); |
2243 | if (ret < 0) | ||
2244 | goto err1; | ||
2243 | 2245 | ||
2244 | /* Noone else will be downing sem now, so we won't sleep */ | 2246 | /* Noone else will be downing sem now, so we won't sleep */ |
2245 | xt_register_target(&ipt_standard_target); | 2247 | ret = xt_register_target(&ipt_standard_target); |
2246 | xt_register_target(&ipt_error_target); | 2248 | if (ret < 0) |
2247 | xt_register_match(&icmp_matchstruct); | 2249 | goto err2; |
2250 | ret = xt_register_target(&ipt_error_target); | ||
2251 | if (ret < 0) | ||
2252 | goto err3; | ||
2253 | ret = xt_register_match(&icmp_matchstruct); | ||
2254 | if (ret < 0) | ||
2255 | goto err4; | ||
2248 | 2256 | ||
2249 | /* Register setsockopt */ | 2257 | /* Register setsockopt */ |
2250 | ret = nf_register_sockopt(&ipt_sockopts); | 2258 | ret = nf_register_sockopt(&ipt_sockopts); |
2251 | if (ret < 0) { | 2259 | if (ret < 0) |
2252 | duprintf("Unable to register sockopts.\n"); | 2260 | goto err5; |
2253 | return ret; | ||
2254 | } | ||
2255 | 2261 | ||
2256 | printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); | 2262 | printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); |
2257 | return 0; | 2263 | return 0; |
2264 | |||
2265 | err5: | ||
2266 | xt_unregister_match(&icmp_matchstruct); | ||
2267 | err4: | ||
2268 | xt_unregister_target(&ipt_error_target); | ||
2269 | err3: | ||
2270 | xt_unregister_target(&ipt_standard_target); | ||
2271 | err2: | ||
2272 | xt_proto_fini(AF_INET); | ||
2273 | err1: | ||
2274 | return ret; | ||
2258 | } | 2275 | } |
2259 | 2276 | ||
2260 | static void __exit ip_tables_fini(void) | 2277 | static void __exit ip_tables_fini(void) |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f26898b00347..c9d6b23cd3f7 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1398,23 +1398,39 @@ static int __init ip6_tables_init(void) | |||
1398 | { | 1398 | { |
1399 | int ret; | 1399 | int ret; |
1400 | 1400 | ||
1401 | xt_proto_init(AF_INET6); | 1401 | ret = xt_proto_init(AF_INET6); |
1402 | if (ret < 0) | ||
1403 | goto err1; | ||
1402 | 1404 | ||
1403 | /* Noone else will be downing sem now, so we won't sleep */ | 1405 | /* Noone else will be downing sem now, so we won't sleep */ |
1404 | xt_register_target(&ip6t_standard_target); | 1406 | ret = xt_register_target(&ip6t_standard_target); |
1405 | xt_register_target(&ip6t_error_target); | 1407 | if (ret < 0) |
1406 | xt_register_match(&icmp6_matchstruct); | 1408 | goto err2; |
1409 | ret = xt_register_target(&ip6t_error_target); | ||
1410 | if (ret < 0) | ||
1411 | goto err3; | ||
1412 | ret = xt_register_match(&icmp6_matchstruct); | ||
1413 | if (ret < 0) | ||
1414 | goto err4; | ||
1407 | 1415 | ||
1408 | /* Register setsockopt */ | 1416 | /* Register setsockopt */ |
1409 | ret = nf_register_sockopt(&ip6t_sockopts); | 1417 | ret = nf_register_sockopt(&ip6t_sockopts); |
1410 | if (ret < 0) { | 1418 | if (ret < 0) |
1411 | duprintf("Unable to register sockopts.\n"); | 1419 | goto err5; |
1412 | xt_proto_fini(AF_INET6); | ||
1413 | return ret; | ||
1414 | } | ||
1415 | 1420 | ||
1416 | printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); | 1421 | printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); |
1417 | return 0; | 1422 | return 0; |
1423 | |||
1424 | err5: | ||
1425 | xt_unregister_match(&icmp6_matchstruct); | ||
1426 | err4: | ||
1427 | xt_unregister_target(&ip6t_error_target); | ||
1428 | err3: | ||
1429 | xt_unregister_target(&ip6t_standard_target); | ||
1430 | err2: | ||
1431 | xt_proto_fini(AF_INET6); | ||
1432 | err1: | ||
1433 | return ret; | ||
1418 | } | 1434 | } |
1419 | 1435 | ||
1420 | static void __exit ip6_tables_fini(void) | 1436 | static void __exit ip6_tables_fini(void) |