• Martin Schwidefsky's avatar
    s390/mm: four page table levels vs. fork · 97520d84
    Martin Schwidefsky authored
    commit 3446c13b upstream.
    
    The fork of a process with four page table levels is broken since
    git commit 6252d702 "[S390] dynamic page tables."
    
    All new mm contexts are created with three page table levels and
    an asce limit of 4TB. If the parent has four levels dup_mmap will
    add vmas to the new context which are outside of the asce limit.
    The subsequent call to copy_page_range will walk the three level
    page table structure of the new process with non-zero pgd and pud
    indexes. This leads to memory clobbers as the pgd_index *and* the
    pud_index is added to the mm->pgd pointer without a pgd_deref
    in between.
    
    The init_new_context() function is selecting the number of page
    table levels for a new context. The function is used by mm_init()
    which in turn is called by dup_mm() and mm_alloc(). These two are
    used by fork() and exec(). The init_new_context() function can
    distinguish the two cases by looking at mm->context.asce_limit,
    for fork() the mm struct has been copied and the number of page
    table levels may not change. For exec() the mm_alloc() function
    set the new mm structure to zero, in this case a three-level page
    table is created as the temporary stack space is located at
    STACK_TOP_MAX = 4TB.
    
    This fixes CVE-2016-2143.
    Reported-by: default avatarMarcin Kościelnicki <koriakin@0x04.net>
    Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
    Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
    [bwh: Backported to 3.16:
     - 31-bit s390 is still supported so keep the #ifdef CONFIG_64BIT conditions
     - PMDs are not accounted so don't call mm_inc_nr_pmds()
     - Adjust context]
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    97520d84
pgalloc.h 4.5 KB