From: Dongyang Zhan <zdyzztq@gmail.com>
To: linux-mm@kvack.org
Subject: Possible null pointer dereference in memory_present()
Date: Sun, 3 May 2020 13:53:56 +0800 [thread overview]
Message-ID: <CAFSR4csfEVc_jRkF-KmGhnz9ev=67M7i-Cax09+mD8=rKTKJ=g@mail.gmail.com> (raw)
[-- 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 --]
reply other threads:[~2020-05-03 5:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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='CAFSR4csfEVc_jRkF-KmGhnz9ev=67M7i-Cax09+mD8=rKTKJ=g@mail.gmail.com' \
--to=zdyzztq@gmail.com \
--cc=linux-mm@kvack.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox