Skip to content
  • Mel Gorman's avatar
    mm: mempolicy: Let vma_merge and vma_split handle vma->vm_policy linkages · beb95765
    Mel Gorman authored
    commit 05f144a0
    
     upstream.
    
    Dave Jones' system call fuzz testing tool "trinity" triggered the
    following bug error with slab debugging enabled
    
        =============================================================================
        BUG numa_policy (Not tainted): Poison overwritten
        -----------------------------------------------------------------------------
    
        INFO: 0xffff880146498250-0xffff880146498250. First byte 0x6a instead of 0x6b
        INFO: Allocated in mpol_new+0xa3/0x140 age=46310 cpu=6 pid=32154
         __slab_alloc+0x3d3/0x445
         kmem_cache_alloc+0x29d/0x2b0
         mpol_new+0xa3/0x140
         sys_mbind+0x142/0x620
         system_call_fastpath+0x16/0x1b
        INFO: Freed in __mpol_put+0x27/0x30 age=46268 cpu=6 pid=32154
         __slab_free+0x2e/0x1de
         kmem_cache_free+0x25a/0x260
         __mpol_put+0x27/0x30
         remove_vma+0x68/0x90
         exit_mmap+0x118/0x140
         mmput+0x73/0x110
         exit_mm+0x108/0x130
         do_exit+0x162/0xb90
         do_group_exit+0x4f/0xc0
         sys_exit_group+0x17/0x20
         system_call_fastpath+0x16/0x1b
        INFO: Slab 0xffffea0005192600 objects=27 used=27 fp=0x          (null) flags=0x20000000004080
        INFO: Object 0xffff880146498250 @offset=592 fp=0xffff88014649b9d0
    
    This implied a reference counting bug and the problem happened during
    mbind().
    
    mbind() applies a new memory policy to a range and uses mbind_range() to
    merge existing VMAs or split them as necessary.  In the event of splits,
    mpol_dup() will allocate a new struct mempolicy and maintain existing
    reference counts whose rules are documented in
    Documentation/vm/numa_memory_policy.txt .
    
    The problem occurs with shared memory policies.  The vm_op->set_policy
    increments the reference count if necessary and split_vma() and
    vma_merge() have already handled the existing reference counts.
    However, policy_vma() screws it up by replacing an existing
    vma->vm_policy with one that potentially has the wrong reference count
    leading to a premature free.  This patch removes the damage caused by
    policy_vma().
    
    With this patch applied Dave's trinity tool runs an mbind test for 5
    minutes without error.  /proc/slabinfo reported that there are no
    numa_policy or shared_policy_node objects allocated after the test
    completed and the shared memory region was deleted.
    
    Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
    Cc: Dave Jones <davej@redhat.com>
    Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: Stephen Wilson <wilsons@start.ca>
    Cc: Christoph Lameter <cl@linux.com>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    beb95765