All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Pavel Tatashin <pasha.tatashin@oracle.com>,
	Steven Sistare <steven.sistare@oracle.com>,
	Daniel Jordan <daniel.m.jordan@oracle.com>,
	Bob Picco <bob.picco@oracle.com>, Michal Hocko <mhocko@suse.com>,
	Mel Gorman <mgorman@techsingularity.net>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 4.12 16/41] mm: discard memblock data later
Date: Tue, 22 Aug 2017 12:13:44 -0700	[thread overview]
Message-ID: <20170822190942.585952526@linuxfoundation.org> (raw)
In-Reply-To: <20170822190941.918296529@linuxfoundation.org>

4.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pavel Tatashin <pasha.tatashin@oracle.com>

commit 3010f876500f9ba921afaeccec30c45ca6584dc8 upstream.

There is existing use after free bug when deferred struct pages are
enabled:

The memblock_add() allocates memory for the memory array if more than
128 entries are needed.  See comment in e820__memblock_setup():

  * The bootstrap memblock region count maximum is 128 entries
  * (INIT_MEMBLOCK_REGIONS), but EFI might pass us more E820 entries
  * than that - so allow memblock resizing.

This memblock memory is freed here:
        free_low_memory_core_early()

We access the freed memblock.memory later in boot when deferred pages
are initialized in this path:

        deferred_init_memmap()
                for_each_mem_pfn_range()
                  __next_mem_pfn_range()
                    type = &memblock.memory;

One possible explanation for why this use-after-free hasn't been hit
before is that the limit of INIT_MEMBLOCK_REGIONS has never been
exceeded at least on systems where deferred struct pages were enabled.

Tested by reducing INIT_MEMBLOCK_REGIONS down to 4 from the current 128,
and verifying in qemu that this code is getting excuted and that the
freed pages are sane.

Link: http://lkml.kernel.org/r/1502485554-318703-2-git-send-email-pasha.tatashin@oracle.com
Fixes: 7e18adb4f80b ("mm: meminit: initialise remaining struct pages in parallel with kswapd")
Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
Reviewed-by: Daniel Jordan <daniel.m.jordan@oracle.com>
Reviewed-by: Bob Picco <bob.picco@oracle.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
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>

---
 include/linux/memblock.h |    6 ++++--
 mm/memblock.c            |   40 ++++++++++++++++++----------------------
 mm/nobootmem.c           |   16 ----------------
 mm/page_alloc.c          |    4 ++++
 4 files changed, 26 insertions(+), 40 deletions(-)

--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -65,6 +65,7 @@ extern bool movable_node_enabled;
 #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
 #define __init_memblock __meminit
 #define __initdata_memblock __meminitdata
+void memblock_discard(void);
 #else
 #define __init_memblock
 #define __initdata_memblock
@@ -78,8 +79,6 @@ phys_addr_t memblock_find_in_range_node(
 					int nid, ulong flags);
 phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
 				   phys_addr_t size, phys_addr_t align);
-phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
-phys_addr_t get_allocated_memblock_memory_regions_info(phys_addr_t *addr);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
@@ -114,6 +113,9 @@ void __next_mem_range_rev(u64 *idx, int
 void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
 				phys_addr_t *out_end);
 
+void __memblock_free_early(phys_addr_t base, phys_addr_t size);
+void __memblock_free_late(phys_addr_t base, phys_addr_t size);
+
 /**
  * for_each_mem_range - iterate through memblock areas from type_a and not
  * included in type_b. Or just type_a if type_b is NULL.
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -288,31 +288,27 @@ static void __init_memblock memblock_rem
 }
 
 #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
-
-phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info(
-					phys_addr_t *addr)
-{
-	if (memblock.reserved.regions == memblock_reserved_init_regions)
-		return 0;
-
-	*addr = __pa(memblock.reserved.regions);
-
-	return PAGE_ALIGN(sizeof(struct memblock_region) *
-			  memblock.reserved.max);
-}
-
-phys_addr_t __init_memblock get_allocated_memblock_memory_regions_info(
-					phys_addr_t *addr)
+/**
+ * Discard memory and reserved arrays if they were allocated
+ */
+void __init memblock_discard(void)
 {
-	if (memblock.memory.regions == memblock_memory_init_regions)
-		return 0;
+	phys_addr_t addr, size;
 
-	*addr = __pa(memblock.memory.regions);
-
-	return PAGE_ALIGN(sizeof(struct memblock_region) *
-			  memblock.memory.max);
+	if (memblock.reserved.regions != memblock_reserved_init_regions) {
+		addr = __pa(memblock.reserved.regions);
+		size = PAGE_ALIGN(sizeof(struct memblock_region) *
+				  memblock.reserved.max);
+		__memblock_free_late(addr, size);
+	}
+
+	if (memblock.memory.regions == memblock_memory_init_regions) {
+		addr = __pa(memblock.memory.regions);
+		size = PAGE_ALIGN(sizeof(struct memblock_region) *
+				  memblock.memory.max);
+		__memblock_free_late(addr, size);
+	}
 }
-
 #endif
 
 /**
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -146,22 +146,6 @@ static unsigned long __init free_low_mem
 				NULL)
 		count += __free_memory_core(start, end);
 
-#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
-	{
-		phys_addr_t size;
-
-		/* Free memblock.reserved array if it was allocated */
-		size = get_allocated_memblock_reserved_regions_info(&start);
-		if (size)
-			count += __free_memory_core(start, start + size);
-
-		/* Free memblock.memory array if it was allocated */
-		size = get_allocated_memblock_memory_regions_info(&start);
-		if (size)
-			count += __free_memory_core(start, start + size);
-	}
-#endif
-
 	return count;
 }
 
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1582,6 +1582,10 @@ void __init page_alloc_init_late(void)
 	/* Reinit limits that are based on free pages after the kernel is up */
 	files_maxfiles_init();
 #endif
+#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
+	/* Discard memblock private memory */
+	memblock_discard();
+#endif
 
 	for_each_populated_zone(zone)
 		set_zone_contiguous(zone);

  parent reply	other threads:[~2017-08-22 19:15 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-22 19:13 [PATCH 4.12 00/41] 4.12.9-stable review Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 01/41] audit: Fix use after free in audit_remove_watch_rule() Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 02/41] parisc: pci memory bar assignment fails with 64bit kernels on dino/cujo Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 03/41] crypto: ixp4xx - Fix error handling path in aead_perform() Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 04/41] crypto: x86/sha1 - Fix reads beyond the number of blocks passed Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 05/41] drm/i915: Perform an invalidate prior to executing golden renderstate Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 07/41] Input: elan_i2c - add ELAN0608 to the ACPI table Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 08/41] Input: elan_i2c - Add antoher Lenovo ACPI ID for upcoming Lenovo NB Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 09/41] md: fix test in md_write_start() Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 10/41] md: always clear ->safemode when md_check_recovery gets the mddev lock Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 11/41] MD: not clear ->safemode for external metadata array Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 12/41] ALSA: seq: 2nd attempt at fixing race creating a queue Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 13/41] ALSA: usb-audio: Apply sample rate quirk to Sennheiser headset Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 14/41] ALSA: usb-audio: Add mute TLV for playback volumes on C-Media devices Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 15/41] ALSA: usb-audio: add DSD support for new Amanero PID Greg Kroah-Hartman
2017-08-22 19:13 ` Greg Kroah-Hartman [this message]
2017-08-22 19:13 ` [PATCH 4.12 17/41] slub: fix per memcg cache leak on css offline Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 18/41] mm: fix double mmap_sem unlock on MMF_UNSTABLE enforced SIGBUS Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 19/41] mm/cma_debug.c: fix stack corruption due to sprintf usage Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 20/41] mm/mempolicy: fix use after free when calling get_mempolicy Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 21/41] mm/vmalloc.c: dont unconditonally use __GFP_HIGHMEM Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 22/41] mm: revert x86_64 and arm64 ELF_ET_DYN_BASE base changes Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 24/41] ARM: dts: imx6qdl-nitrogen6_som2: fix PCIe reset Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 25/41] blk-mq-pci: add a fallback when pci_irq_get_affinity returns NULL Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 26/41] powerpc: Fix VSX enabling/flushing to also test MSR_FP and MSR_VEC Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 27/41] xen-blkfront: use a right index when checking requests Greg Kroah-Hartman
2017-08-22 19:13   ` Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 28/41] perf/x86: Fix RDPMC vs. mm_struct tracking Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 29/41] x86/asm/64: Clear AC on NMI entries Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 30/41] x86: Fix norandmaps/ADDR_NO_RANDOMIZE Greg Kroah-Hartman
2017-08-22 19:13 ` [PATCH 4.12 31/41] x86/elf: Remove the unnecessary ADDR_NO_RANDOMIZE checks Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 32/41] irqchip/atmel-aic: Fix unbalanced of_node_put() in aic_common_irq_fixup() Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 33/41] irqchip/atmel-aic: Fix unbalanced refcount in aic_common_rtc_irq_fixup() Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 34/41] genirq: Restore trigger settings in irq_modify_status() Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 35/41] genirq/ipi: Fixup checks against nr_cpu_ids Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 36/41] kernel/watchdog: Prevent false positives with turbo modes Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 37/41] Sanitize move_pages() permission checks Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 38/41] pids: make task_tgid_nr_ns() safe Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 39/41] debug: Fix WARN_ON_ONCE() for modules Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 40/41] usb: optimize acpi companion search for usb port devices Greg Kroah-Hartman
2017-08-22 19:14 ` [PATCH 4.12 41/41] usb: qmi_wwan: add D-Link DWM-222 device ID Greg Kroah-Hartman
2017-08-23  0:33 ` [PATCH 4.12 00/41] 4.12.9-stable review Shuah Khan
2017-08-23  0:48   ` Greg Kroah-Hartman
2017-08-27 18:18 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170822190942.585952526@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=bob.picco@oracle.com \
    --cc=daniel.m.jordan@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@techsingularity.net \
    --cc=mhocko@suse.com \
    --cc=pasha.tatashin@oracle.com \
    --cc=stable@vger.kernel.org \
    --cc=steven.sistare@oracle.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.