diff options
author | Josh Boyer <jwboyer@fedoraproject.org> | 2016-03-16 08:21:56 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@fedoraproject.org> | 2016-03-16 08:21:56 -0400 |
commit | 6f9c14ed9c03161bd1015e0e7d97a4c9a4a68db4 (patch) | |
tree | 2e859e5e577c20d21a4878b9a01f722fbcad01cc | |
parent | cb176ec4e7270bd50538d85f22959b8d79aca3dc (diff) | |
download | kernel-6f9c14ed9c03161bd1015e0e7d97a4c9a4a68db4.tar.gz kernel-6f9c14ed9c03161bd1015e0e7d97a4c9a4a68db4.tar.xz kernel-6f9c14ed9c03161bd1015e0e7d97a4c9a4a68db4.zip |
CVE-2016-3135 ipv4: DoS when destroying a network interface (rhbz 1318172 1318270)
-rw-r--r-- | ipv4-Dont-do-expensive-useless-work-during-inetdev-des.patch | 97 | ||||
-rw-r--r-- | kernel.spec | 6 |
2 files changed, 103 insertions, 0 deletions
diff --git a/ipv4-Dont-do-expensive-useless-work-during-inetdev-des.patch b/ipv4-Dont-do-expensive-useless-work-during-inetdev-des.patch new file mode 100644 index 000000000..48e4762e3 --- /dev/null +++ b/ipv4-Dont-do-expensive-useless-work-during-inetdev-des.patch @@ -0,0 +1,97 @@ +From fbd40ea0180a2d328c5adc61414dc8bab9335ce2 Mon Sep 17 00:00:00 2001 +From: "David S. Miller" <davem@davemloft.net> +Date: Sun, 13 Mar 2016 23:28:00 -0400 +Subject: ipv4: Don't do expensive useless work during inetdev destroy. + +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@openwall.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Tested-by: Cyrill Gorcunov <gorcunov@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 65e76a4..e333bc8 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 4734475..21add55 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 c6eb421..ea91058 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); + } + +-- +cgit v0.12 + diff --git a/kernel.spec b/kernel.spec index fcf1cb13e..b5cf610c6 100644 --- a/kernel.spec +++ b/kernel.spec @@ -619,6 +619,9 @@ Patch664: netfilter-x_tables-check-for-size-overflow.patch #CVE-2016-3134 rhbz 1317383 1317384 Patch665: netfilter-x_tables-deal-with-bogus-nextoffset-values.patch +#CVE-2016-3135 rhbz 1318172 1318270 +Patch666: ipv4-Dont-do-expensive-useless-work-during-inetdev-des.patch + # END OF PATCH DEFINITIONS %endif @@ -2140,6 +2143,9 @@ fi # # %changelog +* Wed Mar 16 2016 Josh Boyer <jwboyer@fedoraproject.org> +- CVE-2016-3135 ipv4: DoS when destroying a network interface (rhbz 1318172 1318270) + * Wed Mar 16 2016 Josh Boyer <jwboyer@fedoraproject.org> - 4.6.0-0.rc0.git2.1 - Linux v4.5-760-g710d60cbf1b3 |