lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251122-tonyk-robust_futex-v6-9-05fea005a0fd@igalia.com>
Date: Sat, 22 Nov 2025 02:50:51 -0300
From: André Almeida <andrealmeid@...lia.com>
To: Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, 
 Peter Zijlstra <peterz@...radead.org>, Darren Hart <dvhart@...radead.org>, 
 Davidlohr Bueso <dave@...olabs.net>, Arnd Bergmann <arnd@...db.de>, 
 Sebastian Andrzej Siewior <bigeasy@...utronix.de>, 
 Waiman Long <longman@...hat.com>, Ryan Houdek <Sonicadvance1@...il.com>
Cc: linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org, 
 linux-api@...r.kernel.org, kernel-dev@...lia.com, 
 André Almeida <andrealmeid@...lia.com>
Subject: [PATCH v6 9/9] futex: Use new robust list API internally

The new robust list API internals can handle any kind of robust list, so
to simplify the code, reuse the same mechanisms for the original API and
when calling the original set syscall, set the head in the array of
lists. The first two indexes of the array of robust lists are reserved
for the original API lists, the native robust list and the compat robust
list.

Signed-off-by: André Almeida <andrealmeid@...lia.com>
---
 include/linux/futex.h   |  4 ----
 include/linux/sched.h   |  5 -----
 kernel/futex/core.c     | 12 ------------
 kernel/futex/syscalls.c | 52 ++++++++++++++++++++++++-------------------------
 4 files changed, 25 insertions(+), 48 deletions(-)

diff --git a/include/linux/futex.h b/include/linux/futex.h
index 3dba249bcd32..ce27f6307c60 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -87,10 +87,6 @@ static inline bool futex_in_32bit_syscall(void)
 
 static inline void futex_init_task(struct task_struct *tsk)
 {
-	tsk->robust_list = NULL;
-#ifdef CONFIG_COMPAT
-	tsk->robust_list32 = NULL;
-#endif
 	tsk->futex_robust_lists = NULL;
 	INIT_LIST_HEAD(&tsk->pi_state_list);
 	tsk->pi_state_cache = NULL;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index de2f3cbe4953..e0f28e7f0a2d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -75,7 +75,6 @@ struct pid_namespace;
 struct pipe_inode_info;
 struct rcu_node;
 struct reclaim_state;
-struct robust_list_head;
 struct root_domain;
 struct rq;
 struct sched_attr;
@@ -1330,11 +1329,7 @@ struct task_struct {
 	u32				rmid;
 #endif
 #ifdef CONFIG_FUTEX
-	struct robust_list_head __user	*robust_list;
 	uintptr_t			*futex_robust_lists;
-#ifdef CONFIG_COMPAT
-	struct robust_list_head32 __user *robust_list32;
-#endif
 	struct list_head		pi_state_list;
 	struct futex_pi_state		*pi_state_cache;
 	struct mutex			futex_exit_mutex;
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 14d8a7176367..f91df175033d 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -1500,18 +1500,6 @@ static void exit_robust_lists(struct task_struct *tsk)
 
 static void futex_cleanup(struct task_struct *tsk)
 {
-	if (unlikely(tsk->robust_list)) {
-		exit_robust_list(tsk, tsk->robust_list);
-		tsk->robust_list = NULL;
-	}
-
-#ifdef CONFIG_64BIT
-	if (unlikely(tsk->robust_list32)) {
-		exit_robust_list32(tsk, tsk->robust_list32);
-		tsk->robust_list32 = NULL;
-	}
-#endif
-
 	if (unlikely(tsk->futex_robust_lists))
 		exit_robust_lists(tsk);
 
diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
index f730d16632fc..2a44791db37a 100644
--- a/kernel/futex/syscalls.c
+++ b/kernel/futex/syscalls.c
@@ -28,32 +28,29 @@
 SYSCALL_DEFINE2(set_robust_list, struct robust_list_head __user *, head,
 		size_t, len)
 {
+	enum robust_list2_cmd cmd;
 	/*
 	 * The kernel knows only one size for now:
 	 */
 	if (unlikely(len != sizeof(*head)))
 		return -EINVAL;
 
-	current->robust_list = head;
+	cmd = IS_ENABLED(CONFIG_64BIT) ? FUTEX_ROBUST_LIST_CMD_SET_64 :
+	      FUTEX_ROBUST_LIST_CMD_SET_32;
 
-	return 0;
+	return futex_robust_list_set((uintptr_t) head, cmd,
+				     FUTEX_ROBUST_LIST_NATIVE_IDX);
 }
 
-static inline void __user *futex_task_robust_list(struct task_struct *p, bool compat)
-{
-#ifdef CONFIG_COMPAT
-	if (compat)
-		return p->robust_list32;
-#endif
-	return p->robust_list;
-}
-
-static void __user *futex_get_robust_list_common(int pid, bool compat, int index)
+static void __user *futex_get_robust_list_common(int pid, unsigned int index)
 {
 	struct task_struct *p = current;
 	void __user *head;
 	int ret;
 
+	if (index >= FUTEX_ROBUST_LIST2_MAX_IDX)
+		return (void __user *)ERR_PTR(-EINVAL);
+
 	scoped_guard(rcu) {
 		if (pid) {
 			p = find_task_by_vpid(pid);
@@ -75,14 +72,10 @@ static void __user *futex_get_robust_list_common(int pid, bool compat, int index
 	if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
 		goto err_unlock;
 
-	if (index >= 0) {
-		scoped_guard(mutex, &p->futex_exit_mutex) {
-			uintptr_t *rl = p->futex_robust_lists;
+	scoped_guard(mutex, &p->futex_exit_mutex) {
+		uintptr_t *rl = p->futex_robust_lists;
 
-			head = rl ? (void __user *) rl[index] : NULL;
-		}
-	} else {
-		head = futex_task_robust_list(p, compat);
+		head = rl ? (void __user *) rl[index] : NULL;
 	}
 
 	up_read(&p->signal->exec_update_lock);
@@ -107,7 +100,11 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
 		struct robust_list_head __user * __user *, head_ptr,
 		size_t __user *, len_ptr)
 {
-	struct robust_list_head __user *head = futex_get_robust_list_common(pid, false, -1);
+	struct robust_list_head __user *head =
+		futex_get_robust_list_common(pid, FUTEX_ROBUST_LIST_NATIVE_IDX);
+
+	head = (struct robust_list_head __user *)
+		((uintptr_t) head & FUTEX_ROBUST_LIST_ENTRY_MASK);
 
 	if (IS_ERR(head))
 		return PTR_ERR(head);
@@ -180,7 +177,7 @@ SYSCALL_DEFINE4(get_robust_list2, int, pid,
 	 */
 	index += FUTEX_ROBUST_LIST2_IDX;
 
-	entry_ptr = futex_get_robust_list_common(pid, false, index);
+	entry_ptr = futex_get_robust_list_common(pid, index);
 	if (IS_ERR(entry_ptr))
 		return PTR_ERR(entry_ptr);
 
@@ -568,22 +565,23 @@ COMPAT_SYSCALL_DEFINE2(set_robust_list,
 	if (unlikely(len != sizeof(*head)))
 		return -EINVAL;
 
-	current->robust_list32 = head;
-
-	return 0;
+	return futex_robust_list_set((uintptr_t) head, FUTEX_ROBUST_LIST_CMD_SET_32,
+				     FUTEX_ROBUST_LIST_COMPAT_IDX);
 }
 
 COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid,
 			compat_uptr_t __user *, head_ptr,
 			compat_size_t __user *, len_ptr)
 {
-	struct robust_list_head32 __user *head = futex_get_robust_list_common(pid, true, -1);
+	struct robust_list_head32 __user *head =
+		futex_get_robust_list_common(pid, FUTEX_ROBUST_LIST_COMPAT_IDX);
 
-	if (IS_ERR(head))
-		return PTR_ERR(head);
+	head = (struct robust_list_head32 __user *)
+		((uintptr_t) head & FUTEX_ROBUST_LIST_ENTRY_MASK);
 
 	if (put_user(sizeof(*head), len_ptr))
 		return -EFAULT;
+
 	return put_user(ptr_to_compat(head), head_ptr);
 }
 #endif /* CONFIG_COMPAT */

-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ