[RFC PATCH v2 23/41] statx: report UUID and GUID owners

Jan Koester jan.koester at tuxist.de
Wed Oct 21 03:15:43 UTC 2026


Add stx_uid_r and stx_gid_r, the owner and group as __kernel_uid_r_t,
taking 40 of the 64 spare bytes at the end of struct statx, and
STATX_UID_R and STATX_GID_R for them. Every filesystem provides them,
from the kstat the VFS has anyway. stx_uid and stx_gid keep showing a
UUID or GUID as the overflow id.

struct statx is designed to be extended this way, so there is no new
system call: statx() with the new mask bits is the *_r variant.

Assisted-by: Claude:claude-opus-5-5

Signed-off-by: Jan Koester <jan.koester at tuxist.de>
---
 fs/stat.c                 | 24 +++++++++++++++++++++++-
 include/uapi/linux/stat.h | 10 +++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index c461c30542..993ca4907a 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -185,7 +185,7 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
 	struct inode *inode = d_backing_inode(path->dentry);
 
 	memset(stat, 0, sizeof(*stat));
-	stat->result_mask |= STATX_BASIC_STATS;
+	stat->result_mask |= STATX_BASIC_STATS | STATX_UID_R | STATX_GID_R;
 	query_flags &= AT_STATX_SYNC_TYPE;
 
 	/* allow the fs to override these if it really wants to */
@@ -206,6 +206,17 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
 	stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |
 				  STATX_ATTR_DAX);
 
+	/*
+	 * STATX_UID_R and STATX_GID_R are another view of the owner: ask the
+	 * filesystem for STATX_UID and STATX_GID, and report them whenever
+	 * those are valid, also from a ->getattr() that sets result_mask on
+	 * its own.
+	 */
+	if (request_mask & STATX_UID_R)
+		request_mask |= STATX_UID;
+	if (request_mask & STATX_GID_R)
+		request_mask |= STATX_GID;
+
 	idmap = mnt_idmap(path->mnt);
 	if (inode->i_op->getattr) {
 		int ret;
@@ -218,6 +229,15 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
 		generic_fillattr(idmap, request_mask, inode, stat);
 	}
 
+	if (stat->result_mask & STATX_UID)
+		stat->result_mask |= STATX_UID_R;
+	else
+		stat->result_mask &= ~STATX_UID_R;
+	if (stat->result_mask & STATX_GID)
+		stat->result_mask |= STATX_GID_R;
+	else
+		stat->result_mask &= ~STATX_GID_R;
+
 	/*
 	 * If this is a block device inode, override the filesystem attributes
 	 * with the block device specific parameters that need to be obtained
@@ -711,6 +731,8 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
 	tmp.stx_nlink = stat->nlink;
 	tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);
 	tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);
+	from_kuid_r_munged(current_user_ns(), stat->uid, &tmp.stx_uid_r);
+	from_kgid_r_munged(current_user_ns(), stat->gid, &tmp.stx_gid_r);
 	tmp.stx_mode = stat->mode;
 	tmp.stx_ino = stat->ino;
 	tmp.stx_size = stat->size;
diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
index 1686861aae..689757d8a1 100644
--- a/include/uapi/linux/stat.h
+++ b/include/uapi/linux/stat.h
@@ -3,6 +3,7 @@
 #define _UAPI_LINUX_STAT_H
 
 #include <linux/types.h>
+#include <linux/uidgid_r.h>
 
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
@@ -187,7 +188,12 @@ struct statx {
 	__u32	__spare2[1];
 
 	/* 0xc0 */
-	__u64	__spare3[8];	/* Spare space for future expansion */
+	/* Owner and group, also UUIDs and GUIDs [STATX_UID_R, STATX_GID_R] */
+	__kernel_uid_r_t	stx_uid_r;
+	__kernel_gid_r_t	stx_gid_r;
+
+	/* 0xe8 */
+	__u64	__spare3[3];	/* Spare space for future expansion */
 
 	/* 0x100 */
 };
@@ -219,6 +225,8 @@ struct statx {
 #define STATX_SUBVOL		0x00008000U	/* Want/got stx_subvol */
 #define STATX_WRITE_ATOMIC	0x00010000U	/* Want/got atomic_write_* fields */
 #define STATX_DIO_READ_ALIGN	0x00020000U	/* Want/got dio read alignment info */
+#define STATX_UID_R		0x00040000U	/* Want/got stx_uid_r */
+#define STATX_GID_R		0x00080000U	/* Want/got stx_gid_r */
 
 #define STATX__RESERVED		0x80000000U	/* Reserved for future struct statx expansion */
 
-- 
2.56.0




More information about the Linux-security-module-archive mailing list