Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0eff66e6 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7ee66fcb
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -1170,21 +1170,34 @@ static int __init arp_tables_init(void)
{
	int ret;

	xt_proto_init(NF_ARP);
	ret = xt_proto_init(NF_ARP);
	if (ret < 0)
		goto err1;

	/* Noone else will be downing sem now, so we won't sleep */
	xt_register_target(&arpt_standard_target);
	xt_register_target(&arpt_error_target);
	ret = xt_register_target(&arpt_standard_target);
	if (ret < 0)
		goto err2;
	ret = xt_register_target(&arpt_error_target);
	if (ret < 0)
		goto err3;

	/* Register setsockopt */
	ret = nf_register_sockopt(&arpt_sockopts);
	if (ret < 0) {
		duprintf("Unable to register sockopts.\n");
		return ret;
	}
	if (ret < 0)
		goto err4;

	printk("arp_tables: (C) 2002 David S. Miller\n");
	return 0;

err4:
	xt_unregister_target(&arpt_error_target);
err3:
	xt_unregister_target(&arpt_standard_target);
err2:
	xt_proto_fini(NF_ARP);
err1:
	return ret;
}

static void __exit arp_tables_fini(void)
+25 −8
Original line number Diff line number Diff line
@@ -2239,22 +2239,39 @@ static int __init ip_tables_init(void)
{
	int ret;

	xt_proto_init(AF_INET);
	ret = xt_proto_init(AF_INET);
	if (ret < 0)
		goto err1;

	/* Noone else will be downing sem now, so we won't sleep */
	xt_register_target(&ipt_standard_target);
	xt_register_target(&ipt_error_target);
	xt_register_match(&icmp_matchstruct);
	ret = xt_register_target(&ipt_standard_target);
	if (ret < 0)
		goto err2;
	ret = xt_register_target(&ipt_error_target);
	if (ret < 0)
		goto err3;
	ret = xt_register_match(&icmp_matchstruct);
	if (ret < 0)
		goto err4;

	/* Register setsockopt */
	ret = nf_register_sockopt(&ipt_sockopts);
	if (ret < 0) {
		duprintf("Unable to register sockopts.\n");
		return ret;
	}
	if (ret < 0)
		goto err5;

	printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n");
	return 0;

err5:
	xt_unregister_match(&icmp_matchstruct);
err4:
	xt_unregister_target(&ipt_error_target);
err3:
	xt_unregister_target(&ipt_standard_target);
err2:
	xt_proto_fini(AF_INET);
err1:
	return ret;
}

static void __exit ip_tables_fini(void)
+25 −9
Original line number Diff line number Diff line
@@ -1398,23 +1398,39 @@ static int __init ip6_tables_init(void)
{
	int ret;

	xt_proto_init(AF_INET6);
	ret = xt_proto_init(AF_INET6);
	if (ret < 0)
		goto err1;

	/* Noone else will be downing sem now, so we won't sleep */
	xt_register_target(&ip6t_standard_target);
	xt_register_target(&ip6t_error_target);
	xt_register_match(&icmp6_matchstruct);
	ret = xt_register_target(&ip6t_standard_target);
	if (ret < 0)
		goto err2;
	ret = xt_register_target(&ip6t_error_target);
	if (ret < 0)
		goto err3;
	ret = xt_register_match(&icmp6_matchstruct);
	if (ret < 0)
		goto err4;

	/* Register setsockopt */
	ret = nf_register_sockopt(&ip6t_sockopts);
	if (ret < 0) {
		duprintf("Unable to register sockopts.\n");
		xt_proto_fini(AF_INET6);
		return ret;
	}
	if (ret < 0)
		goto err5;

	printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
	return 0;

err5:
	xt_unregister_match(&icmp6_matchstruct);
err4:
	xt_unregister_target(&ip6t_error_target);
err3:
	xt_unregister_target(&ip6t_standard_target);
err2:
	xt_proto_fini(AF_INET6);
err1:
	return ret;
}

static void __exit ip6_tables_fini(void)