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>] [day] [month] [year] [list]
Message-ID: <20251110102908.3634466-1-tiantao6@hisilicon.com>
Date: Mon, 10 Nov 2025 18:29:08 +0800
From: Tian Tao <tiantao6@...ilicon.com>
To: <brauner@...nel.org>, <jack@...e.cz>, <cyphar@...har.com>,
	<linux-kernel@...r.kernel.org>
Subject: [PATCH] userns: use acquire/release semantics for idmap nr_extents

Replace plain loads followed by smp_rmb() with smp_load_acquire() when
reading uid/gid/projid map->nr_extents, and replace the writer side
sequence of smp_wmb(); map->nr_extents = val with an explicit
smp_store_release(&map->nr_extents, val) when installing a new idmap.

Signed-off-by: Tian Tao <tiantao6@...ilicon.com>
---
 kernel/user_namespace.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 03cb63883d04..213f7814dc45 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -318,8 +318,11 @@ map_id_range_down_base(unsigned extents, struct uid_gid_map *map, u32 id, u32 co
 static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count)
 {
 	struct uid_gid_extent *extent;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
+/* Acquire semantics: pair with the writer's smp_store_release()
+ * when publishing a new map->nr_extents so that readers see the
+ * extent array contents that were written before nr_extents.
+ */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 
 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
 		extent = map_id_range_down_base(extents, map, id, count);
@@ -384,8 +387,11 @@ map_id_range_up_max(unsigned extents, struct uid_gid_map *map, u32 id, u32 count
 u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
 {
 	struct uid_gid_extent *extent;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
+/* Acquire semantics: pair with the writer's smp_store_release()
+ * when publishing a new map->nr_extents so that readers see the
+ * extent array contents that were written before nr_extents.
+ */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 
 	if (extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
 		extent = map_id_range_up_base(extents, map, id, count);
@@ -677,8 +683,11 @@ static void *m_start(struct seq_file *seq, loff_t *ppos,
 		     struct uid_gid_map *map)
 {
 	loff_t pos = *ppos;
-	unsigned extents = map->nr_extents;
-	smp_rmb();
+/* Acquire semantics: pair with the writer's smp_store_release()
+ * when publishing a new map->nr_extents so that readers see the
+ * extent array contents that were written before nr_extents.
+ */
+	unsigned int extents = smp_load_acquire(&map->nr_extents);
 
 	if (pos >= extents)
 		return NULL;
@@ -1099,8 +1108,12 @@ static ssize_t map_write(struct file *file, const char __user *buf,
 		map->forward = new_map.forward;
 		map->reverse = new_map.reverse;
 	}
-	smp_wmb();
-	map->nr_extents = new_map.nr_extents;
+	/* Release semantics: publish the extent arrays (map->forward/map->reverse
+	 * or map->extent) and then update map->nr_extents. Readers use
+	 * smp_load_acquire(&map->nr_extents) so they will see the array contents
+	 * written before this store.
+	 */
+	smp_store_release(&map->nr_extents, new_map.nr_extents);
 
 	*ppos = count;
 	ret = count;
-- 
2.33.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ