[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250712192202.707192-7-gatlin.newhouse@gmail.com>
Date: Sat, 12 Jul 2025 19:21:51 +0000
From: Gatlin Newhouse <gatlin.newhouse@...il.com>
To: linux-hardening@...r.kernel.org
Cc: Gatlin Newhouse <gatlin.newhouse@...il.com>
Subject: [RFC v1 06/17] futex: add get_user_no_dfcache() functions
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
Powered by blists - more mailing lists