From: Greg Kroah-Hartman Date: Tue, 10 May 2022 11:19:10 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.9.313~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ff19a7d8c7b9891d2cca5e6ace6a24bba1e0a06;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches 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 --- 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 index 00000000000..c836b130a29 --- /dev/null +++ b/queue-5.4/block-map-add-__gfp_zero-flag-for-alloc_page-in-function-bio_copy_kern.patch @@ -0,0 +1,35 @@ +From cc8f7fe1f5eab010191aa4570f27641876fa1267 Mon Sep 17 00:00:00 2001 +From: Haimin Zhang +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 + +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 +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20220216084038.15635-1-tcs.kernel@gmail.com +Signed-off-by: Jens Axboe +[nobelbarakat: Backported to 5.4: Manually added __GFP_ZERO flag] +Signed-off-by: Nobel Barakat +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..c0a809e6d70 --- /dev/null +++ b/queue-5.4/mm-fix-unexpected-zeroed-page-mapping-with-zram-swap.patch @@ -0,0 +1,156 @@ +From e914d8f00391520ecc4495dd0ca0124538ab7119 Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Thu, 14 Apr 2022 19:13:46 -0700 +Subject: mm: fix unexpected zeroed page mapping with zram swap + +From: Minchan Kim + +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 +Tested-by: Ivan Babrou +Signed-off-by: Minchan Kim +Cc: Nitin Gupta +Cc: Sergey Senozhatsky +Cc: Jens Axboe +Cc: David Hildenbrand +Cc: [4.14+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..fde25509dde --- /dev/null +++ b/queue-5.4/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch @@ -0,0 +1,95 @@ +From 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c Mon Sep 17 00:00:00 2001 +From: "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 + +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 +Signed-off-by: David S. Miller +[jnixdorf: context updated for bpo to v4.19/v5.4] +Signed-off-by: Johannes Nixdorf +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + diff --git a/queue-5.4/series b/queue-5.4/series index a27fb4509a8..286e9201d6e 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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