Commit 584eab29 authored by Taehee Yoo's avatar Taehee Yoo Committed by Pablo Neira Ayuso

netfilter: add missing error handling code for register functions

register_{netdevice/inetaddr/inet6addr}_notifier may return an error
value, this patch adds the code to handle these error paths.
Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 508b0904
...@@ -9,7 +9,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum, ...@@ -9,7 +9,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
const struct nf_nat_range2 *range, const struct nf_nat_range2 *range,
const struct net_device *out); const struct net_device *out);
void nf_nat_masquerade_ipv4_register_notifier(void); int nf_nat_masquerade_ipv4_register_notifier(void);
void nf_nat_masquerade_ipv4_unregister_notifier(void); void nf_nat_masquerade_ipv4_unregister_notifier(void);
#endif /*_NF_NAT_MASQUERADE_IPV4_H_ */ #endif /*_NF_NAT_MASQUERADE_IPV4_H_ */
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
unsigned int unsigned int
nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
const struct net_device *out); const struct net_device *out);
void nf_nat_masquerade_ipv6_register_notifier(void); int nf_nat_masquerade_ipv6_register_notifier(void);
void nf_nat_masquerade_ipv6_unregister_notifier(void); void nf_nat_masquerade_ipv6_unregister_notifier(void);
#endif /* _NF_NAT_MASQUERADE_IPV6_H_ */ #endif /* _NF_NAT_MASQUERADE_IPV6_H_ */
...@@ -81,9 +81,12 @@ static int __init masquerade_tg_init(void) ...@@ -81,9 +81,12 @@ static int __init masquerade_tg_init(void)
int ret; int ret;
ret = xt_register_target(&masquerade_tg_reg); ret = xt_register_target(&masquerade_tg_reg);
if (ret)
return ret;
if (ret == 0) ret = nf_nat_masquerade_ipv4_register_notifier();
nf_nat_masquerade_ipv4_register_notifier(); if (ret)
xt_unregister_target(&masquerade_tg_reg);
return ret; return ret;
} }
......
...@@ -149,16 +149,29 @@ static struct notifier_block masq_inet_notifier = { ...@@ -149,16 +149,29 @@ static struct notifier_block masq_inet_notifier = {
static atomic_t masquerade_notifier_refcount = ATOMIC_INIT(0); static atomic_t masquerade_notifier_refcount = ATOMIC_INIT(0);
void nf_nat_masquerade_ipv4_register_notifier(void) int nf_nat_masquerade_ipv4_register_notifier(void)
{ {
int ret;
/* check if the notifier was already set */ /* check if the notifier was already set */
if (atomic_inc_return(&masquerade_notifier_refcount) > 1) if (atomic_inc_return(&masquerade_notifier_refcount) > 1)
return; return 0;
/* Register for device down reports */ /* Register for device down reports */
register_netdevice_notifier(&masq_dev_notifier); ret = register_netdevice_notifier(&masq_dev_notifier);
if (ret)
goto err_dec;
/* Register IP address change reports */ /* Register IP address change reports */
register_inetaddr_notifier(&masq_inet_notifier); ret = register_inetaddr_notifier(&masq_inet_notifier);
if (ret)
goto err_unregister;
return ret;
err_unregister:
unregister_netdevice_notifier(&masq_dev_notifier);
err_dec:
atomic_dec(&masquerade_notifier_refcount);
return ret;
} }
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4_register_notifier); EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4_register_notifier);
......
...@@ -69,7 +69,9 @@ static int __init nft_masq_ipv4_module_init(void) ...@@ -69,7 +69,9 @@ static int __init nft_masq_ipv4_module_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
nf_nat_masquerade_ipv4_register_notifier(); ret = nf_nat_masquerade_ipv4_register_notifier();
if (ret)
nft_unregister_expr(&nft_masq_ipv4_type);
return ret; return ret;
} }
......
...@@ -58,8 +58,12 @@ static int __init masquerade_tg6_init(void) ...@@ -58,8 +58,12 @@ static int __init masquerade_tg6_init(void)
int err; int err;
err = xt_register_target(&masquerade_tg6_reg); err = xt_register_target(&masquerade_tg6_reg);
if (err == 0) if (err)
nf_nat_masquerade_ipv6_register_notifier(); return err;
err = nf_nat_masquerade_ipv6_register_notifier();
if (err)
xt_unregister_target(&masquerade_tg6_reg);
return err; return err;
} }
......
...@@ -132,8 +132,8 @@ static void iterate_cleanup_work(struct work_struct *work) ...@@ -132,8 +132,8 @@ static void iterate_cleanup_work(struct work_struct *work)
* of ipv6 addresses being deleted), we also need to add an upper * of ipv6 addresses being deleted), we also need to add an upper
* limit to the number of queued work items. * limit to the number of queued work items.
*/ */
static int masq_inet_event(struct notifier_block *this, static int masq_inet6_event(struct notifier_block *this,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct inet6_ifaddr *ifa = ptr; struct inet6_ifaddr *ifa = ptr;
const struct net_device *dev; const struct net_device *dev;
...@@ -171,20 +171,34 @@ static int masq_inet_event(struct notifier_block *this, ...@@ -171,20 +171,34 @@ static int masq_inet_event(struct notifier_block *this,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static struct notifier_block masq_inet_notifier = { static struct notifier_block masq_inet6_notifier = {
.notifier_call = masq_inet_event, .notifier_call = masq_inet6_event,
}; };
static atomic_t masquerade_notifier_refcount = ATOMIC_INIT(0); static atomic_t masquerade_notifier_refcount = ATOMIC_INIT(0);
void nf_nat_masquerade_ipv6_register_notifier(void) int nf_nat_masquerade_ipv6_register_notifier(void)
{ {
int ret;
/* check if the notifier is already set */ /* check if the notifier is already set */
if (atomic_inc_return(&masquerade_notifier_refcount) > 1) if (atomic_inc_return(&masquerade_notifier_refcount) > 1)
return; return 0;
register_netdevice_notifier(&masq_dev_notifier); ret = register_netdevice_notifier(&masq_dev_notifier);
register_inet6addr_notifier(&masq_inet_notifier); if (ret)
goto err_dec;
ret = register_inet6addr_notifier(&masq_inet6_notifier);
if (ret)
goto err_unregister;
return ret;
err_unregister:
unregister_netdevice_notifier(&masq_dev_notifier);
err_dec:
atomic_dec(&masquerade_notifier_refcount);
return ret;
} }
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_register_notifier); EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_register_notifier);
...@@ -194,7 +208,7 @@ void nf_nat_masquerade_ipv6_unregister_notifier(void) ...@@ -194,7 +208,7 @@ void nf_nat_masquerade_ipv6_unregister_notifier(void)
if (atomic_dec_return(&masquerade_notifier_refcount) > 0) if (atomic_dec_return(&masquerade_notifier_refcount) > 0)
return; return;
unregister_inet6addr_notifier(&masq_inet_notifier); unregister_inet6addr_notifier(&masq_inet6_notifier);
unregister_netdevice_notifier(&masq_dev_notifier); unregister_netdevice_notifier(&masq_dev_notifier);
} }
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_unregister_notifier); EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_unregister_notifier);
...@@ -70,7 +70,9 @@ static int __init nft_masq_ipv6_module_init(void) ...@@ -70,7 +70,9 @@ static int __init nft_masq_ipv6_module_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
nf_nat_masquerade_ipv6_register_notifier(); ret = nf_nat_masquerade_ipv6_register_notifier();
if (ret)
nft_unregister_expr(&nft_masq_ipv6_type);
return ret; return ret;
} }
......
...@@ -214,7 +214,9 @@ static int __init nft_flow_offload_module_init(void) ...@@ -214,7 +214,9 @@ static int __init nft_flow_offload_module_init(void)
{ {
int err; int err;
register_netdevice_notifier(&flow_offload_netdev_notifier); err = register_netdevice_notifier(&flow_offload_netdev_notifier);
if (err)
goto err;
err = nft_register_expr(&nft_flow_offload_type); err = nft_register_expr(&nft_flow_offload_type);
if (err < 0) if (err < 0)
...@@ -224,6 +226,7 @@ static int __init nft_flow_offload_module_init(void) ...@@ -224,6 +226,7 @@ static int __init nft_flow_offload_module_init(void)
register_expr: register_expr:
unregister_netdevice_notifier(&flow_offload_netdev_notifier); unregister_netdevice_notifier(&flow_offload_netdev_notifier);
err:
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment