• Akinobu Mita's avatar
    fork: fix error handling in dup_task() · f19b9f74
    Akinobu Mita authored
    The function dup_task() may fail at the following function calls in the
    following order.
    
    0) alloc_task_struct_node()
    1) alloc_thread_info_node()
    2) arch_dup_task_struct()
    
    Error by 0) is not a matter, it can just return.  But error by 1) requires
    releasing task_struct allocated by 0) before it returns.  Likewise, error
    by 2) requires releasing task_struct and thread_info allocated by 0) and
    1).
    
    The existing error handling calls free_task_struct() and
    free_thread_info() which do not only release task_struct and thread_info,
    but also call architecture specific arch_release_task_struct() and
    arch_release_thread_info().
    
    The problem is that task_struct and thread_info are not fully initialized
    yet at this point, but arch_release_task_struct() and
    arch_release_thread_info() are called with them.
    
    For example, x86 defines its own arch_release_task_struct() that releases
    a task_xstate.  If alloc_thread_info_node() fails in dup_task(),
    arch_release_task_struct() is called with task_struct which is just
    allocated and filled with garbage in this error handling.
    
    This actually happened with tools/testing/fault-injection/failcmd.sh
    
    	# env FAILCMD_TYPE=fail_page_alloc \
    		./tools/testing/fault-injection/failcmd.sh --times=100 \
    		--min-order=0 --ignore-gfp-wait=0 \
    		-- make -C tools/testing/selftests/ run_tests
    
    In order to fix this issue, make free_{task_struct,thread_info}() not to
    call arch_release_{task_struct,thread_info}() and call
    arch_release_{task_struct,thread_info}() implicitly where needed.
    
    Default arch_release_task_struct() and arch_release_thread_info() are
    defined as empty by default.  So this change only affects the
    architectures which implement their own arch_release_task_struct() or
    arch_release_thread_info() as listed below.
    
    arch_release_task_struct(): x86, sh
    arch_release_thread_info(): mn10300, tile
    Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: David Howells <dhowells@redhat.com>
    Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
    Cc: Paul Mundt <lethal@linux-sh.org>
    Cc: Chris Metcalf <cmetcalf@tilera.com>
    Cc: Salman Qazi <sqazi@google.com>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f19b9f74
fork.c 44.3 KB