Add disabled cache get_user function calls to futex functions to disable using the SafeFetch cache on any fast userspace mutexes. --- kernel/futex/core.c | 5 +++++ kernel/futex/futex.h | 4 ++++ kernel/futex/pi.c | 5 +++++ kernel/futex/requeue.c | 5 ++++- kernel/futex/waitwake.c | 4 ++++ 5 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 90d53fb0ee9e..0ad5e0dba881 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -1023,8 +1023,13 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, return -1; retry: +#ifdef CONFIG_SAFEFETCH + if (get_user_no_dfcache(uval, uaddr)) + return -1; +#else if (get_user(uval, uaddr)) return -1; +#endif /* * Special case for regular (non PI) futexes. The unlock path in diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h index fcd1617212ee..515338cf4289 100644 --- a/kernel/futex/futex.h +++ b/kernel/futex/futex.h @@ -308,7 +308,11 @@ static __always_inline int futex_get_value(u32 *dest, u32 __user *from) from = masked_user_access_begin(from); else if (!user_read_access_begin(from, sizeof(*from))) return -EFAULT; +#ifdef CONFIG_SAFEFETCH + unsafe_get_user_no_dfcache(val, from, Efault); +#else unsafe_get_user(val, from, Efault); +#endif user_read_access_end(); *dest = val; return 0; diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c index dacb2330f1fb..f9f4ac192338 100644 --- a/kernel/futex/pi.c +++ b/kernel/futex/pi.c @@ -1140,8 +1140,13 @@ int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) return -ENOSYS; retry: +#ifdef CONFIG_SAFEFETCH + if (get_user_no_dfcache(uval, uaddr)) + return -EFAULT; +#else if (get_user(uval, uaddr)) return -EFAULT; +#endif /* * We release only a lock we actually own: */ diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c index c716a66f8692..3ebc08a9a8e8 100644 --- a/kernel/futex/requeue.c +++ b/kernel/futex/requeue.c @@ -468,8 +468,11 @@ int futex_requeue(u32 __user *uaddr1, unsigned int flags1, if (unlikely(ret)) { futex_hb_waiters_dec(hb2); double_unlock_hb(hb1, hb2); - +#ifdef CONFIG_SAFEFETCH + ret = get_user_no_dfcache(curval, uaddr1); +#else ret = get_user(curval, uaddr1); +#endif if (ret) return ret; diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c index e2bbe5509ec2..bf4ed107aff8 100644 --- a/kernel/futex/waitwake.c +++ b/kernel/futex/waitwake.c @@ -629,7 +629,11 @@ int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, if (ret) { futex_q_unlock(hb); +#ifdef CONFIG_SAFEFETCH + ret = get_user_no_dfcache(uval, uaddr); +#else ret = get_user(uval, uaddr); +#endif if (ret) return ret; -- 2.25.1