Skip to content
  • Michal Hocko's avatar
    mm, oom: fix potential data corruption when oom_reaper races with writer · 6b31d595
    Michal Hocko authored
    Wenwei Tao has noticed that our current assumption that the oom victim
    is dying and never doing any visible changes after it dies, and so the
    oom_reaper can tear it down, is not entirely true.
    
    __task_will_free_mem consider a task dying when SIGNAL_GROUP_EXIT is set
    but do_group_exit sends SIGKILL to all threads _after_ the flag is set.
    So there is a race window when some threads won't have
    fatal_signal_pending while the oom_reaper could start unmapping the
    address space.  Moreover some paths might not check for fatal signals
    before each PF/g-u-p/copy_from_user.
    
    We already have a protection for oom_reaper vs.  PF races by checking
    MMF_UNSTABLE.  This has been, however, checked only for kernel threads
    (use_mm users) which can outlive the oom victim.  A simple fix would be
    to extend the current check in handle_mm_fault for all tasks but that
    wouldn't be sufficient because the current check assumes that a kernel
    thread would bail out after EFAULT from get_user*/copy_from_user and
    never re-read the same address which would succeed because the PF path
    has established page tables already.  This seems to be the case for the
    only existing use_mm user currently (virtio driver) but it is rather
    fragile in general.
    
    This is even more fragile in general for more complex paths such as
    generic_perform_write which can re-read the same address more times
    (e.g.  iov_iter_copy_from_user_atomic to fail and then
    iov_iter_fault_in_readable on retry).
    
    Therefore we have to implement MMF_UNSTABLE protection in a robust way
    and never make a potentially corrupted content visible.  That requires
    to hook deeper into the PF path and check for the flag _every time_
    before a pte for anonymous memory is established (that means all
    !VM_SHARED mappings).
    
    The corruption can be triggered artificially
    (http://lkml.kernel.org/r/201708040646.v746kkhC024636@www262.sakura.ne.jp)
    but there doesn't seem to be any real life bug report.  The race window
    should be quite tight to trigger most of the time.
    
    Link: http://lkml.kernel.org/r/20170807113839.16695-3-mhocko@kernel.org
    Fixes: aac45363
    
     ("mm, oom: introduce oom reaper")
    Signed-off-by: default avatarMichal Hocko <mhocko@suse.com>
    Reported-by: default avatarWenwei Tao <wenwei.tww@alibaba-inc.com>
    Tested-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
    Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
    Cc: Andrea Argangeli <andrea@kernel.org>
    Cc: David Rientjes <rientjes@google.com>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    6b31d595