[BUG] Use of probe_kernel_address() in task_rcu_dereference() without checking return value
From: Russell King - ARM Linux admin
Date: Fri Aug 30 2019 - 10:08:31 EST
In commit 150593bf8693 ("sched/api: Introduce task_rcu_dereference() and
try_get_task_struct()") probe_kernel_address() is used without checking
it's return value, resulting in undefined behaviour of this function.
I stumbled over this due to looking at the definition of this function,
due to a patch submission for ARM, and delving into the internals of the
probe_kernel_*() functions.
Essentially, probe_kernel_address() uses probe_kernel_read(), which
eventually uses __copy_from_user_inatomic().
__copy_from_user_inatomic() is defined thusly:
* NOTE: only copy_from_user() zero-pads the destination in case of short copy.
* Neither __copy_from_user() nor __copy_from_user_inatomic() zero anything
* at all; their callers absolutely must check the return value.
which means that when probe_kernel_address() returns -EFAULT, the
destination is left uninitialised. In the case of
task_rcu_dereference(), this means that "siginfo" can be used without
having been initialised, resulting in this function returning an
indeterminant result (based on the value of an uninitialised variable
on the stack.)
One option would be to explicitly initialise "sighand" on function
entry, or maybe check the return value of probe_kernel_address(). It
looks non-trivial due to the interaction with put_task_struct(). I
suggest someone who knows this code needs to patch this issue.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up