]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 May 2022 11:18:59 +0000 (13:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 May 2022 11:18:59 +0000 (13:18 +0200)
added patches:
net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch

queue-4.14/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch b/queue-4.14/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
new file mode 100644 (file)
index 0000000..cd1653a
--- /dev/null
@@ -0,0 +1,95 @@
+From 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c Mon Sep 17 00:00:00 2001
+From: "j.nixdorf@avm.de" <j.nixdorf@avm.de>
+Date: Thu, 24 Feb 2022 10:06:49 +0100
+Subject: net: ipv6: ensure we call ipv6_mc_down() at most once
+
+From: j.nixdorf@avm.de <j.nixdorf@avm.de>
+
+commit 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c upstream.
+
+There are two reasons for addrconf_notify() to be called with NETDEV_DOWN:
+either the network device is actually going down, or IPv6 was disabled
+on the interface.
+
+If either of them stays down while the other is toggled, we repeatedly
+call the code for NETDEV_DOWN, including ipv6_mc_down(), while never
+calling the corresponding ipv6_mc_up() in between. This will cause a
+new entry in idev->mc_tomb to be allocated for each multicast group
+the interface is subscribed to, which in turn leaks one struct ifmcaddr6
+per nontrivial multicast group the interface is subscribed to.
+
+The following reproducer will leak at least $n objects:
+
+ip addr add ff2e::4242/32 dev eth0 autojoin
+sysctl -w net.ipv6.conf.eth0.disable_ipv6=1
+for i in $(seq 1 $n); do
+       ip link set up eth0; ip link set down eth0
+done
+
+Joining groups with IPV6_ADD_MEMBERSHIP (unprivileged) or setting the
+sysctl net.ipv6.conf.eth0.forwarding to 1 (=> subscribing to ff02::2)
+can also be used to create a nontrivial idev->mc_list, which will the
+leak objects with the right up-down-sequence.
+
+Based on both sources for NETDEV_DOWN events the interface IPv6 state
+should be considered:
+
+ - not ready if the network interface is not ready OR IPv6 is disabled
+   for it
+ - ready if the network interface is ready AND IPv6 is enabled for it
+
+The functions ipv6_mc_up() and ipv6_down() should only be run when this
+state changes.
+
+Implement this by remembering when the IPv6 state is ready, and only
+run ipv6_mc_down() if it actually changed from ready to not ready.
+
+The other direction (not ready -> ready) already works correctly, as:
+
+ - the interface notification triggered codepath for NETDEV_UP /
+   NETDEV_CHANGE returns early if ipv6 is disabled, and
+ - the disable_ipv6=0 triggered codepath skips fully initializing the
+   interface as long as addrconf_link_ready(dev) returns false
+ - calling ipv6_mc_up() repeatedly does not leak anything
+
+Fixes: 3ce62a84d53c ("ipv6: exit early in addrconf_notify() if IPv6 is disabled")
+Signed-off-by: Johannes Nixdorf <j.nixdorf@avm.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[jnixdorf: context updated for bpo to v4.9/v4.14]
+Signed-off-by: Johannes Nixdorf <j.nixdorf@avm.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/addrconf.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -3580,6 +3580,7 @@ static int addrconf_ifdown(struct net_de
+       struct list_head del_list;
+       int _keep_addr;
+       bool keep_addr;
++      bool was_ready;
+       int state, i;
+       ASSERT_RTNL();
+@@ -3643,7 +3644,10 @@ restart:
+       addrconf_del_rs_timer(idev);
+-      /* Step 2: clear flags for stateless addrconf */
++      /* Step 2: clear flags for stateless addrconf, repeated down
++       *         detection
++       */
++      was_ready = idev->if_flags & IF_READY;
+       if (!how)
+               idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
+@@ -3730,7 +3734,7 @@ restart:
+       if (how) {
+               ipv6_ac_destroy_dev(idev);
+               ipv6_mc_destroy_dev(idev);
+-      } else {
++      } else if (was_ready) {
+               ipv6_mc_down(idev);
+       }
index 6e62b4899bea4f3b2b30bbd3bef3bd813efd99f4..b6cf46c3b8ec7636f661d5e36476a2d33a604702 100644 (file)
@@ -73,3 +73,4 @@ net-igmp-respect-rcu-rules-in-ip_mc_source-and-ip_mc_msfilter.patch
 hwmon-adt7470-fix-warning-on-module-removal.patch-27384
 kvm-x86-cpuid-only-provide-cpuid-leaf-0xa-if-host-ha.patch
 nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-do.patch
+net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch