[PATCH RFC v3 10/90] user: add uid_range_in_use()

From: Josef Bacik

Date: Thu Nov 05 2026 - 10:03:07 EST


A user_struct is looked up by a bare kuid and does not pin a user
namespace. So it can still exist after the cell that used the kuid is
gone. If the block is then lent to another cell, that cell would find the
old user_struct.

Add uid_range_in_use(), so that the block allocator can ask whether a
user_struct exists for any kuid in a range.

Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
include/linux/sched/user.h | 1 +
kernel/user.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+)

diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index ec262b605437..5966e355db9f 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -55,5 +55,6 @@ static inline struct user_struct *get_uid(struct user_struct *u)
return u;
}
extern void free_uid(struct user_struct *);
+bool uid_range_in_use(kuid_t first, kuid_t last);

#endif /* _LINUX_SCHED_USER_H */
diff --git a/kernel/user.c b/kernel/user.c
index 21bafdc11379..b69cab2a5a3b 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -154,6 +154,38 @@ static void user_epoll_free(struct user_struct *up)
#endif
}

+#ifdef CONFIG_CELLS
+/**
+ * uid_range_in_use - is there a user_struct for any uid of a range?
+ * @first: the first uid of the range
+ * @last: the last
+ *
+ * A user_struct is keyed by a bare kuid and pins no user namespace. The id block
+ * allocator asks before it lends a block, and before it takes one back.
+ *
+ * Return: true if there is one.
+ */
+bool uid_range_in_use(kuid_t first, kuid_t last)
+{
+ struct user_struct *user;
+ unsigned long flags;
+ bool ret = false;
+ int i;
+
+ spin_lock_irqsave(&uidhash_lock, flags);
+ for (i = 0; i < UIDHASH_SZ && !ret; i++) {
+ hlist_for_each_entry(user, &uidhash_table[i], uidhash_node) {
+ if (uid_gte(user->uid, first) && uid_lte(user->uid, last)) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&uidhash_lock, flags);
+ return ret;
+}
+#endif
+
/* IRQs are disabled and uidhash_lock is held upon function entry.
* IRQ state (as stored in flags) is restored and uidhash_lock released
* upon function exit.

--
2.55.0