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/ipv4 | |
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/ipv4')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 27 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 33 |
2 files changed, 45 insertions, 15 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) |