linux/mm
Ingo Molnar bead9a3abd mm: sparsemem memory_present() fix
Fix memory corruption and crash on 32-bit x86 systems.

If a !PAE x86 kernel is booted on a 32-bit system with more than 4GB of
RAM, then we call memory_present() with a start/end that goes outside
the scope of MAX_PHYSMEM_BITS.

That causes this loop to happily walk over the limit of the sparse
memory section map:

    for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
                unsigned long section = pfn_to_section_nr(pfn);
                struct mem_section *ms;

                sparse_index_init(section, nid);
                set_section_nid(section, nid);

                ms = __nr_to_section(section);
                if (!ms->section_mem_map)
                        ms->section_mem_map = sparse_encode_early_nid(nid) |
			                                SECTION_MARKED_PRESENT;

'ms' will be out of bounds and we'll corrupt a small amount of memory by
encoding the node ID and writing SECTION_MARKED_PRESENT (==0x1) over it.

The corruption might happen when encoding a non-zero node ID, or due to
the SECTION_MARKED_PRESENT which is 0x1:

	mmzone.h:#define	SECTION_MARKED_PRESENT	(1UL<<0)

The fix is to sanity check anything the architecture passes to
sparsemem.

This bug seems to be rather old (as old as sparsemem support itself),
but the exact incarnation depended on random details like configs, which
made this bug more prominent in v2.6.25-to-be.

An additional enhancement might be to print a warning about ignored or
trimmed memory ranges.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Tested-by: Christoph Lameter <clameter@sgi.com>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Yinghai Lu <Yinghai.Lu@sun.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-04-15 19:30:19 -07:00
..
allocpercpu.c alloc_percpu() fails to allocate percpu data 2008-03-04 16:35:11 -08:00
backing-dev.c mm/backing-dev.c: fix percpu_counter_destroy call bug in bdi_init 2007-12-05 09:21:18 -08:00
bootmem.c mm: fix boundary checking in free_bootmem_core 2008-03-24 19:22:19 -07:00
bounce.c
dmapool.c
fadvise.c check ADVICE of fadvise64_64 even if get_xip_page is given 2008-02-05 09:44:19 -08:00
filemap.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
filemap_xip.c Use pgoff_t instead of unsigned long 2008-02-08 09:22:32 -08:00
fremap.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
highmem.c mm: highmem kernel-doc additions 2008-03-19 18:53:35 -07:00
hugetlb.c hugetlb: fix potential livelock in return_unused_surplus_hugepages() 2008-03-26 15:01:33 -07:00
internal.h Solve section mismatch for free_area_init_core. 2008-02-23 17:13:24 -08:00
Kconfig sh: Bump number of quicklists for SH-5. 2008-01-28 13:18:55 +09:00
madvise.c
Makefile Memory controller: rename to Memory Resource Controller 2008-03-04 16:35:12 -08:00
memcontrol.c memcg: fix node_state handling 2008-04-08 18:25:53 -07:00
memory.c memcg: when do_swap's do_wp_page fails 2008-03-04 16:35:14 -08:00
memory_hotplug.c Page allocator: clean up pcp draining functions 2008-02-05 09:44:17 -08:00
mempolicy.c mempolicy: fix reference counting bugs 2008-03-10 18:01:19 -07:00
mempool.c
migrate.c memcg: fix VM_BUG_ON from page migration 2008-03-04 16:35:14 -08:00
mincore.c
mlock.c
mmap.c mm: special mapping nopage 2008-02-08 18:57:39 -08:00
mmzone.c
mprotect.c
mremap.c
msync.c
nommu.c nommu: add new vmalloc_user() and remap_vmalloc_range() interfaces. 2008-02-05 09:44:21 -08:00
oom_kill.c mm/oom_kill: fix kernel-doc 2008-03-19 18:53:35 -07:00
page-writeback.c writeback: speed up writeback of big dirty files 2008-02-05 09:44:19 -08:00
page_alloc.c memcg: bad page if page_cgroup when free 2008-03-04 16:35:15 -08:00
page_io.c mm: fix PageUptodate data race 2008-02-05 09:44:19 -08:00
page_isolation.c
pagewalk.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
pdflush.c
prio_tree.c
quicklist.c quicklists: Only consider memory that can be used with GFP_KERNEL 2008-01-14 08:52:22 -08:00
readahead.c mm/readahead: fix kernel-doc notation 2008-03-19 18:53:37 -07:00
rmap.c mm: rmap kernel-doc fixes 2008-03-19 18:53:35 -07:00
shmem.c mm/shmem and tiny-shmem: fix some kernel-doc 2008-03-19 18:53:35 -07:00
shmem_acl.c
slab.c slab: fix cache_cache bootstrap in kmem_cache_init() 2008-03-26 10:44:17 -07:00
slob.c slob: reduce external fragmentation by using three free lists 2008-02-05 09:44:19 -08:00
slub.c Fix undefined count_partial if !CONFIG_SLABINFO 2008-04-01 12:44:06 -07:00
sparse-vmemmap.c NULL noise: fs/*, mm/*, kernel/* 2008-03-30 14:18:41 -07:00
sparse.c mm: sparsemem memory_present() fix 2008-04-15 19:30:19 -07:00
swap.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
swap_state.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
swapfile.c d_path: Make seq_path() use a struct path argument 2008-02-14 21:17:08 -08:00
thrash.c
tiny-shmem.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2008-03-25 08:57:47 -07:00
truncate.c docbook: fix kernel-api source files 2008-03-03 10:47:14 -08:00
util.c
vmalloc.c mm: fix various kernel-doc comments 2008-03-19 18:53:35 -07:00
vmscan.c revert "kswapd should only wait on IO if there is IO" 2008-03-24 19:22:19 -07:00
vmstat.c vmstat: remove prefetch 2008-02-05 09:44:18 -08:00