]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 May 2022 11:19:10 +0000 (13:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 May 2022 11:19:10 +0000 (13:19 +0200)
added patches:
block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch
mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch
net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch

queue-5.4/block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch [new file with mode: 0644]
queue-5.4/mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch [new file with mode: 0644]
queue-5.4/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch b/queue-5.4/block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch
new file mode 100644 (file)
index 0000000..c836b13
--- /dev/null
@@ -0,0 +1,35 @@
+From cc8f7fe1f5eab010191aa4570f27641876fa1267 Mon Sep 17 00:00:00 2001
+From: Haimin Zhang <tcs.kernel@gmail.com>
+Date: Wed, 16 Feb 2022 16:40:38 +0800
+Subject: block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern
+
+From: Haimin Zhang <tcs.kernel@gmail.com>
+
+commit cc8f7fe1f5eab010191aa4570f27641876fa1267 upstream.
+
+Add __GFP_ZERO flag for alloc_page in function bio_copy_kern to initialize
+the buffer of a bio.
+
+Signed-off-by: Haimin Zhang <tcs.kernel@gmail.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20220216084038.15635-1-tcs.kernel@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+[nobelbarakat: Backported to 5.4: Manually added __GFP_ZERO flag]
+Signed-off-by: Nobel Barakat <nobelbarakat@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/bio.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1627,7 +1627,7 @@ struct bio *bio_copy_kern(struct request
+               if (bytes > len)
+                       bytes = len;
+-              page = alloc_page(q->bounce_gfp | gfp_mask);
++              page = alloc_page(q->bounce_gfp | __GFP_ZERO | gfp_mask);
+               if (!page)
+                       goto cleanup;
diff --git a/queue-5.4/mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch b/queue-5.4/mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch
new file mode 100644 (file)
index 0000000..c0a809e
--- /dev/null
@@ -0,0 +1,156 @@
+From e914d8f00391520ecc4495dd0ca0124538ab7119 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 14 Apr 2022 19:13:46 -0700
+Subject: mm: fix unexpected zeroed page mapping with zram swap
+
+From: Minchan Kim <minchan@kernel.org>
+
+commit e914d8f00391520ecc4495dd0ca0124538ab7119 upstream.
+
+Two processes under CLONE_VM cloning, user process can be corrupted by
+seeing zeroed page unexpectedly.
+
+      CPU A                        CPU B
+
+  do_swap_page                do_swap_page
+  SWP_SYNCHRONOUS_IO path     SWP_SYNCHRONOUS_IO path
+  swap_readpage valid data
+    swap_slot_free_notify
+      delete zram entry
+                              swap_readpage zeroed(invalid) data
+                              pte_lock
+                              map the *zero data* to userspace
+                              pte_unlock
+  pte_lock
+  if (!pte_same)
+    goto out_nomap;
+  pte_unlock
+  return and next refault will
+  read zeroed data
+
+The swap_slot_free_notify is bogus for CLONE_VM case since it doesn't
+increase the refcount of swap slot at copy_mm so it couldn't catch up
+whether it's safe or not to discard data from backing device.  In the
+case, only the lock it could rely on to synchronize swap slot freeing is
+page table lock.  Thus, this patch gets rid of the swap_slot_free_notify
+function.  With this patch, CPU A will see correct data.
+
+      CPU A                        CPU B
+
+  do_swap_page                do_swap_page
+  SWP_SYNCHRONOUS_IO path     SWP_SYNCHRONOUS_IO path
+                              swap_readpage original data
+                              pte_lock
+                              map the original data
+                              swap_free
+                                swap_range_free
+                                  bd_disk->fops->swap_slot_free_notify
+  swap_readpage read zeroed data
+                              pte_unlock
+  pte_lock
+  if (!pte_same)
+    goto out_nomap;
+  pte_unlock
+  return
+  on next refault will see mapped data by CPU B
+
+The concern of the patch would increase memory consumption since it
+could keep wasted memory with compressed form in zram as well as
+uncompressed form in address space.  However, most of cases of zram uses
+no readahead and do_swap_page is followed by swap_free so it will free
+the compressed form from in zram quickly.
+
+Link: https://lkml.kernel.org/r/YjTVVxIAsnKAXjTd@google.com
+Fixes: 0bcac06f27d7 ("mm, swap: skip swapcache for swapin of synchronous device")
+Reported-by: Ivan Babrou <ivan@cloudflare.com>
+Tested-by: Ivan Babrou <ivan@cloudflare.com>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: <stable@vger.kernel.org>   [4.14+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/page_io.c |   54 ------------------------------------------------------
+ 1 file changed, 54 deletions(-)
+
+--- a/mm/page_io.c
++++ b/mm/page_io.c
+@@ -69,54 +69,6 @@ void end_swap_bio_write(struct bio *bio)
+       bio_put(bio);
+ }
+-static void swap_slot_free_notify(struct page *page)
+-{
+-      struct swap_info_struct *sis;
+-      struct gendisk *disk;
+-      swp_entry_t entry;
+-
+-      /*
+-       * There is no guarantee that the page is in swap cache - the software
+-       * suspend code (at least) uses end_swap_bio_read() against a non-
+-       * swapcache page.  So we must check PG_swapcache before proceeding with
+-       * this optimization.
+-       */
+-      if (unlikely(!PageSwapCache(page)))
+-              return;
+-
+-      sis = page_swap_info(page);
+-      if (!(sis->flags & SWP_BLKDEV))
+-              return;
+-
+-      /*
+-       * The swap subsystem performs lazy swap slot freeing,
+-       * expecting that the page will be swapped out again.
+-       * So we can avoid an unnecessary write if the page
+-       * isn't redirtied.
+-       * This is good for real swap storage because we can
+-       * reduce unnecessary I/O and enhance wear-leveling
+-       * if an SSD is used as the as swap device.
+-       * But if in-memory swap device (eg zram) is used,
+-       * this causes a duplicated copy between uncompressed
+-       * data in VM-owned memory and compressed data in
+-       * zram-owned memory.  So let's free zram-owned memory
+-       * and make the VM-owned decompressed page *dirty*,
+-       * so the page should be swapped out somewhere again if
+-       * we again wish to reclaim it.
+-       */
+-      disk = sis->bdev->bd_disk;
+-      entry.val = page_private(page);
+-      if (disk->fops->swap_slot_free_notify && __swap_count(entry) == 1) {
+-              unsigned long offset;
+-
+-              offset = swp_offset(entry);
+-
+-              SetPageDirty(page);
+-              disk->fops->swap_slot_free_notify(sis->bdev,
+-                              offset);
+-      }
+-}
+-
+ static void end_swap_bio_read(struct bio *bio)
+ {
+       struct page *page = bio_first_page_all(bio);
+@@ -132,7 +84,6 @@ static void end_swap_bio_read(struct bio
+       }
+       SetPageUptodate(page);
+-      swap_slot_free_notify(page);
+ out:
+       unlock_page(page);
+       WRITE_ONCE(bio->bi_private, NULL);
+@@ -371,11 +322,6 @@ int swap_readpage(struct page *page, boo
+       ret = bdev_read_page(sis->bdev, swap_page_sector(page), page);
+       if (!ret) {
+-              if (trylock_page(page)) {
+-                      swap_slot_free_notify(page);
+-                      unlock_page(page);
+-              }
+-
+               count_vm_event(PSWPIN);
+               return 0;
+       }
diff --git a/queue-5.4/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch b/queue-5.4/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
new file mode 100644 (file)
index 0000000..fde2550
--- /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.19/v5.4]
+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
+@@ -3715,6 +3715,7 @@ static int addrconf_ifdown(struct net_de
+       struct inet6_dev *idev;
+       struct inet6_ifaddr *ifa, *tmp;
+       bool keep_addr = false;
++      bool was_ready;
+       int state, i;
+       ASSERT_RTNL();
+@@ -3780,7 +3781,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);
+@@ -3854,7 +3858,7 @@ restart:
+       if (how) {
+               ipv6_ac_destroy_dev(idev);
+               ipv6_mc_destroy_dev(idev);
+-      } else {
++      } else if (was_ready) {
+               ipv6_mc_down(idev);
+       }
index a27fb4509a8ad1bb91b2ccf4bd3dd8d013e98a4e..286e9201d6e58953149c308522eed6c1005e749a 100644 (file)
@@ -38,3 +38,6 @@ kvm-x86-cpuid-only-provide-cpuid-leaf-0xa-if-host-ha.patch
 nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-do.patch
 x86-kvm-preserve-bsp-msr_kvm_poll_control-across-sus.patch
 kvm-lapic-enable-timer-posted-interrupt-only-when-mw.patch
+net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
+block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch
+mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch