]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
netfilter: add missing error handling code for register functions
authorTaehee Yoo <ap420073@gmail.com>
Thu, 22 Nov 2018 10:59:46 +0000 (19:59 +0900)
committerSultan Alsawaf <sultan.alsawaf@canonical.com>
Wed, 24 Jul 2019 15:45:11 +0000 (09:45 -0600)
BugLink: https://bugs.launchpad.net/bugs/1837161
[ Upstream commit 584eab291c67894cb17cc87544b9d086228ea70f ]

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 <ap420073@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
include/net/netfilter/ipv4/nf_nat_masquerade.h
include/net/netfilter/ipv6/nf_nat_masquerade.h
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
net/ipv4/netfilter/nft_masq_ipv4.c
net/ipv6/netfilter/ip6t_MASQUERADE.c
net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
net/ipv6/netfilter/nft_masq_ipv6.c

index ebd869473603af5dc8f6225ff6b3c05008a40e06..03e21bb174a9b9bedef75a1025882207e7c00b0c 100644 (file)
@@ -9,7 +9,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
                       const struct nf_nat_range *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_ */
index 1ed4f2631ed6db65e1bc6d427495a8892fabeb99..92d36466a50be927cc99bf051ce137b5d86053de 100644 (file)
@@ -5,7 +5,7 @@
 unsigned int
 nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range *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_ */
index a03e4e7ef5f90eb55fdf8aba91ccf3b635ffb4ff..8d3f83b3d819bda1f9c6f1298e240ca034b5643a 100644 (file)
@@ -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;
 }
index 0c366aad89cb47bcad1e553f388825a40730f6d9..2c0f03f2d2f4feb22c234660a424423ab3b52282 100644 (file)
@@ -134,16 +134,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);
 
index f18677277119305aeea043d81deb4e6ee7d20b7c..0a7ac261d8a2ff8015042aca83a615167301c215 100644 (file)
@@ -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;
 }
index 92c0047e7e33dc5925054c41143fe200db06f125..3d6f79096154337f3404971b57ce5f3832b66491 100644 (file)
@@ -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;
 }
index 98f61fcb91088cfebd1e77d998f3b445816e0ef2..728fd9ea81b17d0ccfe0d8275987d1cc8c5290fb 100644 (file)
@@ -121,8 +121,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;
@@ -159,20 +159,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);
 
@@ -182,7 +196,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);
index 4146536e9c1517fc5e2e0ad066a8e87154446dda..e561abcb508c20fb7c63fa2799e75f7330759a4d 100644 (file)
@@ -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;
 }