linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* Possible null pointer dereference in memory_present()
@ 2020-05-03  5:53 Dongyang Zhan
  0 siblings, 0 replies; only message in thread
From: Dongyang Zhan @ 2020-05-03  5:53 UTC (permalink / raw)
  To: linux-mm

[-- Attachment #1: Type: text/plain, Size: 2298 bytes --]

Hi,

I found a potential bug in /mm/sparse.c.

So, I hope you can help me to confirm it.


In Linux 4.10.17, memory_present() in /mm/sparse.c does not handles
the failure of ms = __nr_to_section(section), causing a null pointer
dereference bug. If ms = __nr_to_section(section) fails, which makes
ms a null pointer. accessing ms->section_mem_map will trigger a bug.

void __init memory_present(int nid, unsigned long start, unsigned long end)
{
	unsigned long pfn;

	start &= PAGE_SECTION_MASK;
	mminit_validate_memmodel_limits(&start, &end);
	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); //does not handle the failure.
		if (!ms->section_mem_map) //null pointer dereference bug
			ms->section_mem_map = sparse_encode_early_nid(nid) |
							SECTION_MARKED_PRESENT;
	}
}
Let us see sparse_index_init(section, nid) in /mm/sparse.c
static int __meminit sparse_index_init(unsigned long section_nr, int nid)
{
	unsigned long root = SECTION_NR_TO_ROOT(section_nr);
	struct mem_section *section;

	if (mem_section[root]) //if mem_section[root] does not exist, the
section will be allocated.
		return -EEXIST;

	section = sparse_index_alloc(nid);
	if (!section)
		return -ENOMEM;// if it fails to allocate the section,
mem_section[root] will be a null pointer.

	mem_section[root] = section;

	return 0;
}
If mem_section[root] does not exist, the section will be allocated.
And, if it fails to allocate the section, mem_section[root] will be a
null pointer. Note that, root is the result of
SECTION_NR_TO_ROOT(section_nr), so
mem_section[SECTION_NR_TO_ROOT(section_nr)] is null.

Then, let us see __nr_to_section() in /include/linux/mmzone.h .
static inline struct mem_section *__nr_to_section(unsigned long nr)
{
	if (!mem_section[SECTION_NR_TO_ROOT(nr)]) // The nr is  nid in __init
memory_present(). So, mem_section[SECTION_NR_TO_ROOT(nr)] is null in
the above case.
		return NULL;
	return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
}
Therefore, this function can return a null pointer. Accessing
ms->section_mem_map in __init memory_present() will trigger a null
pointer dereference bug.

[-- Attachment #2: Type: text/html, Size: 2964 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-03  5:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-03  5:53 Possible null pointer dereference in memory_present() Dongyang Zhan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox