Messages in this thread | | | Date | Fri, 30 Aug 2019 15:08:05 +0100 | From | Russell King - ARM Linux admin <> | Subject | [BUG] Use of probe_kernel_address() in task_rcu_dereference() without checking return value |
| |
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
| |