Skip to content
  • Yu Zhao's avatar
    mm: don't expose page to fast gup before it's ready · 3f6acdde
    Yu Zhao authored
    We don't want to expose page before it's properly setup.  During page
    setup, we may call page_add_new_anon_rmap() which uses non- atomic bit op.
    If page is exposed before it's done, we could overwrite page flags that
    are set by get_user_pages_fast() or its callers.  Here is a non-fatal
    scenario (there might be other fatal problems that I didn't look into):
    
    	CPU 1				CPU1
    set_pte_at()			get_user_pages_fast()
    page_add_new_anon_rmap()		gup_pte_range()
    	__SetPageSwapBacked()			SetPageReferenced()
    
    Fix the problem by delaying set_pte_at() until page is ready.
    
    I didn't observe the race directly.  But I did get few crashes when
    trying to access mem_cgroup of pages returned by get_user_pages_fast().
    Those page were charged and they showed valid mem_cgroup in kdumps.
    So this led me to think the problem came from premature set_pte_at().
    
    I think the fact that nobody complained about this problem is because
    the race only happens when using ksm+swap, and it might not cause any
    fatal problem even so.  Nevertheless, it's nice to have set_pte_at()
    done consistently after rmap is added and page is charged.
    
    Link: http://lkml.kernel.org/r/20180108225632.16332-1-yuzhao@google.com
    
    
    Signed-off-by: default avatarYu Zhao <yuzhao@google.com>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
    3f6acdde