A robust list is implemented in the user space, but the kernel holds the right to walk it. Given that a robust list may implement the priority inheritance method, the approach chosen to inform the kernel of this feature is to encode the LSB of the uaddr of a list entry to walk from. In a PCuABI environment the uaddr is not a raw pointer but a capability and requires special handling.
This commit makes it possible that no matter the kind of uaddr received, this is decoded correctly.
Signed-off-by: Luca Vizzarro Luca.Vizzarro@arm.com --- kernel/futex/core.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 759332a26b5a..689b8be704ae 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -31,6 +31,7 @@ * "The futexes are also cursed." * "But they come in a choice of three flavours!" */ +#include <linux/cheri.h> #include <linux/compat.h> #include <linux/jhash.h> #include <linux/pagemap.h> @@ -750,20 +751,13 @@ static inline int fetch_robust_entry(struct robust_list __user **entry, #endif unsigned int *pi) { - unsigned long uentry; + struct robust_list __user *uentry;
- if (get_user(uentry, (unsigned long __user *)head)) + if (get_user_ptr(uentry, head)) return -EFAULT;
- /* - * TODO [PCuABI] - pointer conversion to be checked - * Each entry points to either next one or head of the list - * so this should probably operate on capabilities and use - * get_user_ptr instead, or validate the capability prior to - * get_user - */ - *entry = uaddr_to_user_ptr(uentry & ~1UL); - *pi = uentry & 1; + *entry = USER_PTR_ALIGN_DOWN(uentry, 2); + *pi = user_ptr_addr(uentry) & 1;
return 0; }