lkml.org 
[lkml]   [2015]   [Mar]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 14/24] mm: pagewalk: call pte_hole() for VM_PFNMAP during walk_page_range
    3.2.68-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Shiraz Hashim <shashim@codeaurora.org>

    commit 23aaed6659df9adfabe9c583e67a36b54e21df46 upstream.

    walk_page_range() silently skips vma having VM_PFNMAP set, which leads
    to undesirable behaviour at client end (who called walk_page_range).
    Userspace applications get the wrong data, so the effect is like just
    confusing users (if the applications just display the data) or sometimes
    killing the processes (if the applications do something with
    misunderstanding virtual addresses due to the wrong data.)

    For example for pagemap_read, when no callbacks are called against
    VM_PFNMAP vma, pagemap_read may prepare pagemap data for next virtual
    address range at wrong index.

    Eventually userspace may get wrong pagemap data for a task.
    Corresponding to a VM_PFNMAP marked vma region, kernel may report
    mappings from subsequent vma regions. User space in turn may account
    more pages (than really are) to the task.

    In my case I was using procmem, procrack (Android utility) which uses
    pagemap interface to account RSS pages of a task. Due to this bug it
    was giving a wrong picture for vmas (with VM_PFNMAP set).

    Fixes: a9ff785e4437 ("mm/pagewalk.c: walk_page_range should avoid VM_PFNMAP areas")
    Signed-off-by: Shiraz Hashim <shashim@codeaurora.org>
    Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    mm/pagewalk.c | 5 ++++-
    1 file changed, 4 insertions(+), 1 deletion(-)

    --- a/mm/pagewalk.c
    +++ b/mm/pagewalk.c
    @@ -200,7 +200,10 @@ int walk_page_range(unsigned long addr,
    */
    if ((vma->vm_start <= addr) &&
    (vma->vm_flags & VM_PFNMAP)) {
    - next = vma->vm_end;
    + if (walk->pte_hole)
    + err = walk->pte_hole(addr, next, walk);
    + if (err)
    + break;
    pgd = pgd_offset(walk->mm, next);
    continue;
    }


    \
     
     \ /
      Last update: 2015-03-04 00:41    [W:4.535 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site