From: Christian Brauner Date: Fri, 1 May 2026 12:58:53 +0000 (+0200) Subject: user-util,storagectl: introduce USERNS_RANGE_SIZE macro X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eaa0073027b06c384b5f5e9cb57ec850ea024728;p=thirdparty%2Fsystemd.git user-util,storagectl: introduce USERNS_RANGE_SIZE macro The mount.storage helper open-codes the conventional 64K UID/GID delegation block size as 0x10000 / 0x10000U in four places. Several other places in the tree do the same (nspawn's arg_uid_range default, homed's mount setup, …), but with no shared name. Add USERNS_RANGE_SIZE in user-util.h alongside UID_NOBODY and friends, and switch storagectl over to it. Other call sites can adopt it incrementally. Signed-off-by: Christian Brauner (Amutable) --- diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 003420dbe3b..a8902aca615 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -90,6 +90,10 @@ int take_etc_passwd_lock(const char *root); #define UID_NOBODY ((uid_t) 65534U) #define GID_NOBODY ((gid_t) 65534U) +/* Conventional size of a user-namespace UID/GID delegation block (64K). + * Untyped so it can be used in both UID and GID contexts without casts. */ +#define USERNS_RANGE_SIZE 0x10000U + /* If REMOUNT_IDMAPPING_HOST_ROOT is set for remount_idmap() we'll include a mapping here that maps the host * root user accessing the idmapped mount to the this user ID on the backing fs. This is the last valid UID in * the *signed* 32-bit range. You might wonder why precisely use this specific UID for this purpose? Well, we diff --git a/src/shared/nsresource.h b/src/shared/nsresource.h index 5633fd9bf35..c26dd4f8a55 100644 --- a/src/shared/nsresource.h +++ b/src/shared/nsresource.h @@ -2,9 +2,10 @@ #pragma once #include "shared-forward.h" +#include "user-util.h" /* Helpful constants for the only numbers of UIDs that can currently be allocated */ -#define NSRESOURCE_UIDS_64K 0x10000U +#define NSRESOURCE_UIDS_64K USERNS_RANGE_SIZE #define NSRESOURCE_UIDS_1 1U int nsresource_connect(sd_varlink **ret); diff --git a/src/storage/storagectl.c b/src/storage/storagectl.c index f88dff29bc8..23d91d6ba12 100644 --- a/src/storage/storagectl.c +++ b/src/storage/storagectl.c @@ -723,25 +723,25 @@ static int run_as_mount_helper(int argc, char *argv[]) { if (!uid_is_valid(p.base_uid) || !gid_is_valid(p.base_gid)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Provider did not report base UID/GID, cannot mount."); - if (p.base_uid > UINT32_MAX - 0x10000U || - p.base_gid > UINT32_MAX - 0x10000U) + if (p.base_uid > UINT32_MAX - USERNS_RANGE_SIZE || + p.base_gid > UINT32_MAX - USERNS_RANGE_SIZE) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Returned base UID/GID out of range."); r = stat_verify_directory(&st); if (r < 0) return log_error_errno(r, "File descriptor for directory volume is not a directory inode: %m"); - if (st.st_uid < p.base_uid || st.st_uid >= p.base_uid + 0x10000 || - st.st_gid < p.base_gid || st.st_gid >= p.base_gid + 0x10000) + if (st.st_uid < p.base_uid || st.st_uid >= p.base_uid + USERNS_RANGE_SIZE || + st.st_gid < p.base_gid || st.st_gid >= p.base_gid + USERNS_RANGE_SIZE) return log_error_errno(SYNTHETIC_ERRNO(EPERM), "File descriptor for directory volume is not owned by base UID/GID range, refusing."); /* Now move the mount into our own UID/GID range */ _cleanup_free_ char *uid_line = asprintf_safe( UID_FMT " " UID_FMT " " UID_FMT "\n", - p.base_uid, (uid_t) 0, (uid_t) 0x10000); + p.base_uid, (uid_t) 0, USERNS_RANGE_SIZE); _cleanup_free_ char *gid_line = asprintf_safe( GID_FMT " " GID_FMT " " GID_FMT "\n", - p.base_gid, (gid_t) 0, (gid_t) 0x10000); + p.base_gid, (gid_t) 0, USERNS_RANGE_SIZE); if (!uid_line || !gid_line) return log_oom();