[linux] 03/04: ipv4: Don't do expensive useless work during inetdev destroy (CVE-2016-3156)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Apr 13 20:27:11 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch master
in repository linux.

commit e01d7b854caf1f8790c763b77ce695a08e0784b4
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Apr 13 21:24:19 2016 +0100

    ipv4: Don't do expensive useless work during inetdev destroy (CVE-2016-3156)
---
 debian/changelog                                   |  1 +
 ...do-expensive-useless-work-during-inetdev-.patch | 94 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 96 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index ee2c5c4..094c951 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -237,6 +237,7 @@ linux (4.5.1-1) UNRELEASED; urgency=medium
   * netfilter: x_tables: Fix parsing of IPT_SO_SET_REPLACE blobs (CVE-2016-3134)
     - validate e->target_offset early
     - make sure e->next_offset covers remaining blob size
+  * ipv4: Don't do expensive useless work during inetdev destroy (CVE-2016-3156)
 
   [ Aurelien Jarno ]
   * [mipsel/mips/config.loongson-2f] Disable VIDEO_CX23885, VIDEO_IVTV,
diff --git a/debian/patches/bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch b/debian/patches/bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch
new file mode 100644
index 0000000..581301c
--- /dev/null
+++ b/debian/patches/bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch
@@ -0,0 +1,94 @@
+From: "David S. Miller" <davem at davemloft.net>
+Date: Sun, 13 Mar 2016 23:28:00 -0400
+Subject: ipv4: Don't do expensive useless work during inetdev destroy.
+Origin: https://git.kernel.org/linus/fbd40ea0180a2d328c5adc61414dc8bab9335ce2
+
+When an inetdev is destroyed, every address assigned to the interface
+is removed.  And in this scenerio we do two pointless things which can
+be very expensive if the number of assigned interfaces is large:
+
+1) Address promotion.  We are deleting all addresses, so there is no
+   point in doing this.
+
+2) A full nf conntrack table purge for every address.  We only need to
+   do this once, as is already caught by the existing
+   masq_dev_notifier so masq_inet_event() can skip this.
+
+Reported-by: Solar Designer <solar at openwall.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+Tested-by: Cyrill Gorcunov <gorcunov at openvz.org>
+---
+ net/ipv4/devinet.c                          |  4 ++++
+ net/ipv4/fib_frontend.c                     |  4 ++++
+ net/ipv4/netfilter/nf_nat_masquerade_ipv4.c | 12 ++++++++++--
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 65e76a48382c..e333bc86bd39 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -334,6 +334,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
+ 
+ 	ASSERT_RTNL();
+ 
++	if (in_dev->dead)
++		goto no_promotions;
++
+ 	/* 1. Deleting primary ifaddr forces deletion all secondaries
+ 	 * unless alias promotion is set
+ 	 **/
+@@ -380,6 +383,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
+ 			fib_del_ifaddr(ifa, ifa1);
+ 	}
+ 
++no_promotions:
+ 	/* 2. Unlink it */
+ 
+ 	*ifap = ifa1->ifa_next;
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 473447593060..21add552e56a 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -922,6 +922,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
+ 		subnet = 1;
+ 	}
+ 
++	if (in_dev->dead)
++		goto no_promotions;
++
+ 	/* Deletion is more complicated than add.
+ 	 * We should take care of not to delete too much :-)
+ 	 *
+@@ -997,6 +1000,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
+ 		}
+ 	}
+ 
++no_promotions:
+ 	if (!(ok & BRD_OK))
+ 		fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
+ 	if (subnet && ifa->ifa_prefixlen < 31) {
+diff --git a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
+index c6eb42100e9a..ea91058b5f6f 100644
+--- a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
++++ b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
+@@ -108,10 +108,18 @@ static int masq_inet_event(struct notifier_block *this,
+ 			   unsigned long event,
+ 			   void *ptr)
+ {
+-	struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
++	struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
+ 	struct netdev_notifier_info info;
+ 
+-	netdev_notifier_info_init(&info, dev);
++	/* The masq_dev_notifier will catch the case of the device going
++	 * down.  So if the inetdev is dead and being destroyed we have
++	 * no work to do.  Otherwise this is an individual address removal
++	 * and we have to perform the flush.
++	 */
++	if (idev->dead)
++		return NOTIFY_DONE;
++
++	netdev_notifier_info_init(&info, idev->dev);
+ 	return masq_device_event(this, event, &info);
+ }
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 2d13011..7a725df 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -140,3 +140,4 @@ bugfix/all/tools-lib-traceevent-fix-use-of-uninitialized-variables.patch
 bugfix/all/scripts-fix-x.509-pem-support-in-sign-file.patch
 bugfix/all/netfilter-x_tables-validate-e-target_offset-early.patch
 bugfix/all/netfilter-x_tables-make-sure-e-next_offset-covers-re.patch
+bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list