On 30/01/2023 12:17, Tudor Cretu wrote:
A subtle ABI change was introduced in compat64 by "clone: Alter clone to accept capabilities". Indeed, since there is no compat handler for clone, the native one is also used for compat64. This is where the way we convert compat64 syscall arguments to native is showing its limits: if a syscall wrapper expects a capability-sized argument, compat_ptr() is used to convert the user-provided 64-bit value to a capability.
In general, this is what we want, and in fact it is the case for the parent_tidptr and child_tidptr arguments of clone, which are ordinary pointers to user data. However, the newsp and tls arguments are special: they specify the value to set registers to. We should not alter these values in any way: in PCuABI, they are capabilities and we set CSP/CTPIDR accordingly, but in hybrid, they are still 64-bit values and we should only set the lower 64 bits of CSP/CTPIDR. This is not the case in compat64 as compat_ptr() is called to turn these 64-bit values into capabilities.
Hi Kevin,
The approach looks good, but I have only one question. Where specifically newsp and tls arguments would become valid capabilities from compat_ptr?
As far as I understand it, compat_ptr is used only when "clone_args_get_user_ptr" is used, but newsp and tls are obtained using "clone_args_get", so the wrapper would never convert it to a capability. Unless I am missing something...
I think you are: this is clone, not clone3 :) As to where the automatic compat_ptr() conversion I mention in the first paragraph occurs, that's specifically in __SC_DELOUSE() in <linux/compat.h>.
Thanks for the review!
Kevin