[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