Skip to content

Commit

Permalink
netfilter: add missing error handling code for register functions
Browse files Browse the repository at this point in the history
register_{netdevice/inetaddr/inet6addr}_notifier may return an error
value, this patch adds the code to handle these error paths.

Signed-off-by: Taehee Yoo <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
  • Loading branch information
TaeheeYoo authored and ummakynes committed Nov 26, 2018
1 parent 508b090 commit 584eab2
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 22 deletions.
2 changes: 1 addition & 1 deletion include/net/netfilter/ipv4/nf_nat_masquerade.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
const struct nf_nat_range2 *range,
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);

#endif /*_NF_NAT_MASQUERADE_IPV4_H_ */
2 changes: 1 addition & 1 deletion include/net/netfilter/ipv6/nf_nat_masquerade.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
unsigned int
nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
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);

#endif /* _NF_NAT_MASQUERADE_IPV6_H_ */
7 changes: 5 additions & 2 deletions net/ipv4/netfilter/ipt_MASQUERADE.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ static int __init masquerade_tg_init(void)
int ret;

ret = xt_register_target(&masquerade_tg_reg);
if (ret)
return ret;

if (ret == 0)
nf_nat_masquerade_ipv4_register_notifier();
ret = nf_nat_masquerade_ipv4_register_notifier();
if (ret)
xt_unregister_target(&masquerade_tg_reg);

return ret;
}
Expand Down
21 changes: 17 additions & 4 deletions net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,29 @@ static struct notifier_block masq_inet_notifier = {

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 */
if (atomic_inc_return(&masquerade_notifier_refcount) > 1)
return;
return 0;

/* 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_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);

Expand Down
4 changes: 3 additions & 1 deletion net/ipv4/netfilter/nft_masq_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ static int __init nft_masq_ipv4_module_init(void)
if (ret < 0)
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;
}
Expand Down
8 changes: 6 additions & 2 deletions net/ipv6/netfilter/ip6t_MASQUERADE.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ static int __init masquerade_tg6_init(void)
int err;

err = xt_register_target(&masquerade_tg6_reg);
if (err == 0)
nf_nat_masquerade_ipv6_register_notifier();
if (err)
return err;

err = nf_nat_masquerade_ipv6_register_notifier();
if (err)
xt_unregister_target(&masquerade_tg6_reg);

return err;
}
Expand Down
32 changes: 23 additions & 9 deletions net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* limit to the number of queued work items.
*/
static int masq_inet_event(struct notifier_block *this,
unsigned long event, void *ptr)
static int masq_inet6_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct inet6_ifaddr *ifa = ptr;
const struct net_device *dev;
Expand Down Expand Up @@ -171,20 +171,34 @@ static int masq_inet_event(struct notifier_block *this,
return NOTIFY_DONE;
}

static struct notifier_block masq_inet_notifier = {
.notifier_call = masq_inet_event,
static struct notifier_block masq_inet6_notifier = {
.notifier_call = masq_inet6_event,
};

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 */
if (atomic_inc_return(&masquerade_notifier_refcount) > 1)
return;
return 0;

register_netdevice_notifier(&masq_dev_notifier);
register_inet6addr_notifier(&masq_inet_notifier);
ret = register_netdevice_notifier(&masq_dev_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);

Expand All @@ -194,7 +208,7 @@ void nf_nat_masquerade_ipv6_unregister_notifier(void)
if (atomic_dec_return(&masquerade_notifier_refcount) > 0)
return;

unregister_inet6addr_notifier(&masq_inet_notifier);
unregister_inet6addr_notifier(&masq_inet6_notifier);
unregister_netdevice_notifier(&masq_dev_notifier);
}
EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6_unregister_notifier);
4 changes: 3 additions & 1 deletion net/ipv6/netfilter/nft_masq_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ static int __init nft_masq_ipv6_module_init(void)
if (ret < 0)
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;
}
Expand Down
5 changes: 4 additions & 1 deletion net/netfilter/nft_flow_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ static int __init nft_flow_offload_module_init(void)
{
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);
if (err < 0)
Expand All @@ -224,6 +226,7 @@ static int __init nft_flow_offload_module_init(void)

register_expr:
unregister_netdevice_notifier(&flow_offload_netdev_notifier);
err:
return err;
}

Expand Down

0 comments on commit 584eab2

Please sign in to comment.