[linux] 02/02: 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
Sat Apr 30 18:09:34 UTC 2016


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

benh pushed a commit to branch jessie-security
in repository linux.

commit 8d4e375822f4e3e7173eab38b659cb3ff105e37e
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Sat Apr 30 20:08:41 2016 +0200

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

diff --git a/debian/changelog b/debian/changelog
index faf0d31..a0cd367 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,8 @@ linux (3.16.7-ckt25-2+deb8u1) UNRELEASED; urgency=medium
     - validate e->target_offset early
     - make sure e->next_offset covers remaining blob size
     - fix unconditional helper
+  * ipv4: Don't do expensive useless work during inetdev destroy.
+    (CVE-2016-3156)
 
   [ Salvatore Bonaccorso ]
   * [x86] USB: usbip: fix potential out-of-bounds write (CVE-2016-3955)
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..1223989
--- /dev/null
+++ b/debian/patches/bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch
@@ -0,0 +1,98 @@
+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>
+Cc: Moritz Muehlenhoff <jmm at inutil.org>
+[ luis: backported to 3.16:
+  - file rename: nf_nat_masquerade_ipv4.c -> ipt_MASQUERADE.c ]
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+---
+ net/ipv4/devinet.c                  |  4 ++++
+ net/ipv4/fib_frontend.c             |  4 ++++
+ net/ipv4/netfilter/ipt_MASQUERADE.c | 12 ++++++++++--
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index aa4b9990dd7a..710fe64fb2f7 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -326,6 +326,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
+ 	 **/
+@@ -372,6 +375,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 255aa9946fe7..7d736cd3ee91 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -812,6 +812,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 :-)
+ 	 *
+@@ -887,6 +890,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/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
+index 00352ce0f0de..3bc1c98aa2f0 100644
+--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
++++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
+@@ -128,10 +128,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 7a38e70..f4b5460 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -667,3 +667,4 @@ bugfix/all/USB-usbip-fix-potential-out-of-bounds-write.patch
 bugfix/all/netfilter-x_tables-validate-e-target_offset-early.patch
 bugfix/all/netfilter-x_tables-make-sure-e-next_offset-covers-remaining-blob.patch
 bugfix/all/netfilter-x_tables-fix-unconditional-helper.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