lkml.org 
[lkml]   [2019]   [Jun]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 1/3] mm: Trigger bug on if a section is not found in __section_nr
    Date
    From: Alastair D'Silva <alastair@d-silva.org>

    If a memory section comes in where the physical address is greater than
    that which is managed by the kernel, this function would not trigger the
    bug and instead return a bogus section number.

    This patch tracks whether the section was actually found, and triggers the
    bug if not.

    Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
    ---
    drivers/base/memory.c | 18 +++++++++++++++---
    mm/sparse.c | 7 ++++++-
    2 files changed, 21 insertions(+), 4 deletions(-)

    diff --git a/drivers/base/memory.c b/drivers/base/memory.c
    index f180427e48f4..9244c122abf1 100644
    --- a/drivers/base/memory.c
    +++ b/drivers/base/memory.c
    @@ -585,13 +585,21 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
    struct memory_block *find_memory_block_hinted(struct mem_section *section,
    struct memory_block *hint)
    {
    - int block_id = base_memory_block_id(__section_nr(section));
    + int block_id, section_nr;
    struct device *hintdev = hint ? &hint->dev : NULL;
    struct device *dev;

    + section_nr = __section_nr(section);
    + if (section_nr < 0) {
    + if (hintdev)
    + put_device(hintdev);
    + return NULL;
    + }
    +
    + block_id = base_memory_block_id(section_nr);
    dev = subsys_find_device_by_id(&memory_subsys, block_id, hintdev);
    - if (hint)
    - put_device(&hint->dev);
    + if (hintdev)
    + put_device(hintdev);
    if (!dev)
    return NULL;
    return to_memory_block(dev);
    @@ -664,6 +672,10 @@ static int init_memory_block(struct memory_block **memory,
    return -ENOMEM;

    scn_nr = __section_nr(section);
    +
    + if (scn_nr < 0)
    + return scn_nr;
    +
    mem->start_section_nr =
    base_memory_block_id(scn_nr) * sections_per_block;
    mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
    diff --git a/mm/sparse.c b/mm/sparse.c
    index fd13166949b5..57a1a3d9c1cf 100644
    --- a/mm/sparse.c
    +++ b/mm/sparse.c
    @@ -113,10 +113,15 @@ int __section_nr(struct mem_section* ms)
    continue;

    if ((ms >= root) && (ms < (root + SECTIONS_PER_ROOT)))
    - break;
    + break;
    }

    VM_BUG_ON(!root);
    + if (root_nr == NR_SECTION_ROOTS) {
    + VM_BUG_ON(true);
    +
    + return -EINVAL;
    + }

    return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
    }
    --
    2.21.0
    \
     
     \ /
      Last update: 2019-06-26 08:12    [W:3.085 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site