Skip to content
  • Martin Schwidefsky's avatar
    kernel/kmod: fix use-after-free of the sub_info structure · 0baf2a4d
    Martin Schwidefsky authored
    
    
    Found this in the message log on a s390 system:
    
        BUG kmalloc-192 (Not tainted): Poison overwritten
        Disabling lock debugging due to kernel taint
        INFO: 0x00000000684761f4-0x00000000684761f7. First byte 0xff instead of 0x6b
        INFO: Allocated in call_usermodehelper_setup+0x70/0x128 age=71 cpu=2 pid=648
         __slab_alloc.isra.47.constprop.56+0x5f6/0x658
         kmem_cache_alloc_trace+0x106/0x408
         call_usermodehelper_setup+0x70/0x128
         call_usermodehelper+0x62/0x90
         cgroup_release_agent+0x178/0x1c0
         process_one_work+0x36e/0x680
         worker_thread+0x2f0/0x4f8
         kthread+0x10a/0x120
         kernel_thread_starter+0x6/0xc
         kernel_thread_starter+0x0/0xc
        INFO: Freed in call_usermodehelper_exec+0x110/0x1b8 age=71 cpu=2 pid=648
         __slab_free+0x94/0x560
         kfree+0x364/0x3e0
         call_usermodehelper_exec+0x110/0x1b8
         cgroup_release_agent+0x178/0x1c0
         process_one_work+0x36e/0x680
         worker_thread+0x2f0/0x4f8
         kthread+0x10a/0x120
         kernel_thread_starter+0x6/0xc
         kernel_thread_starter+0x0/0xc
    
    There is a use-after-free bug on the subprocess_info structure allocated
    by the user mode helper.  In case do_execve() returns with an error
    ____call_usermodehelper() stores the error code to sub_info->retval, but
    sub_info can already have been freed.
    
    Regarding UMH_NO_WAIT, the sub_info structure can be freed by
    __call_usermodehelper() before the worker thread returns from
    do_execve(), allowing memory corruption when do_execve() failed after
    exec_mmap() is called.
    
    Regarding UMH_WAIT_EXEC, the call to umh_complete() allows
    call_usermodehelper_exec() to continue which then frees sub_info.
    
    To fix this race the code needs to make sure that the call to
    call_usermodehelper_freeinfo() is always done after the last store to
    sub_info->retval.
    
    Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
    Reviewed-by: default avatarOleg 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>
    0baf2a4d