[RFC PATCH v2 35/41] Documentation: describe UUID and GUID user and group ids

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


Describe __kernel_uid_r_t, the rules for UUID and GUID ids (overflow
ids in classic interfaces, the initial user namespace only, filesystems
with SB_I_UID_R), the *_r system calls, the extended interfaces (statx,
socket credentials, siginfo, SysV IPC, keyctl, POSIX ACLs, procfs,
audit) and the current limitations.

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

Signed-off-by: Jan Koester <jan.koester at tuxist.de>
---
 Documentation/userspace-api/index.rst |   1 +
 Documentation/userspace-api/uid_r.rst | 169 ++++++++++++++++++++++++++
 2 files changed, 170 insertions(+)
 create mode 100644 Documentation/userspace-api/uid_r.rst

diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
index a68b1bea57..fcac7703fa 100644
--- a/Documentation/userspace-api/index.rst
+++ b/Documentation/userspace-api/index.rst
@@ -22,6 +22,7 @@ System calls
    ioctl/index
    mseal
    rseq
+   uid_r
 
 Security-related interfaces
 ===========================
diff --git a/Documentation/userspace-api/uid_r.rst b/Documentation/userspace-api/uid_r.rst
new file mode 100644
index 0000000000..c080485455
--- /dev/null
+++ b/Documentation/userspace-api/uid_r.rst
@@ -0,0 +1,169 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================================
+UUID and GUID user and group ids (``*_r``)
+===========================================
+
+Besides the classic 32 bit numbers, user and group ids can be UUIDs
+(RFC 9562, version 4) or Microsoft GUIDs. A process can run as such a
+user, files can be owned by one, and ACLs, keys, IPC objects, sockets and
+signals carry them. The classic system calls keep their 32 bit ids; a new
+family of calls, named after them with an ``_r`` suffix, and extensions of
+existing interfaces handle all kinds of id.
+
+The id type
+===========
+
+``<linux/uidgid_r.h>`` defines ``__kernel_uid_r_t`` (and
+``__kernel_gid_r_t``, the same type)::
+
+	typedef struct __kernel_uid_r {
+		__u32 type;
+		union {
+			__u32 legacy;
+			__u8 uuid[16];
+			__u8 guid[16];
+		};
+	} __kernel_uid_r_t;
+
+``type`` is one of:
+
+``UID_R_NONE`` (0)
+	No id. An all-zero id is never root. The ``set*id_r()`` and
+	``chown_r()`` calls take it, like a ``NULL`` pointer or a classic
+	``-1``, as "leave unchanged".
+
+``UID_R_LEGACY`` (1)
+	A classic id in ``legacy``.
+
+``UID_R_UUID`` (2)
+	A UUID in ``uuid``, in network byte order. It must be version 4 with
+	the RFC 9562 variant.
+
+``UID_R_GUID`` (3)
+	A GUID in ``guid`` as Windows stores it: Data1, Data2 and Data3
+	little endian. The nil GUID is not allowed.
+
+Bytes past the member ``type`` selects must be zero. The struct is 20
+bytes on every ABI, so none of the calls needs a compat variant.
+
+The text form of an id (in procfs, audit records, key descriptions and
+``/proc/<pid>/loginuid``) is a decimal number, a UUID
+``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`` or a GUID in braces
+``{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}``.
+
+Rules
+=====
+
+- Interfaces with 32 bit ids show a UUID or GUID as the overflow id
+  (``/proc/sys/kernel/overflowuid`` and ``overflowgid``), as the 16 bit
+  system calls do for ids above 65535.
+
+- UUIDs and GUIDs are not part of any ``uid_map`` or ``gid_map``: they
+  exist in the initial user namespace only. Elsewhere they show as the
+  overflow id, can't be set, and no capability in another namespace gives
+  privilege over them. Only ``CAP_SETUID``/``CAP_SETGID`` in the initial
+  namespace can switch to one.
+
+- Idmapped mounts map classic ids and pass UUIDs and GUIDs unchanged, on
+  filesystems of the initial user namespace.
+
+- Only filesystems that can store them accept UUID and GUID owners and ACL
+  entries; others refuse with ``EOVERFLOW``, for ``chown`` as well as for
+  creating a file as such a user. tmpfs and ramfs do, and ext4 with the
+  ``uid_r`` feature (``mke2fs -O uid_r``; a read-only compatible feature,
+  inodes of at least 256 bytes). ``tune2fs -O uid_r`` turns it on later; on
+  a mounted filesystem through ``EXT4_IOC_SET_TUNE_SB_PARAM``, which makes
+  it usable at once, otherwise at the next mount or remount.
+
+System calls
+============
+
+All take pointers to ``__kernel_uid_r_t`` and return 0 or a negative
+error, unless noted otherwise.
+
+=================  =======================================================
+``getuid_r``       ``(uid_r *uid)``, also ``geteuid_r``, ``getgid_r``,
+                   ``getegid_r``
+``setuid_r``       ``(const uid_r *uid)``, also ``setgid_r``
+``setreuid_r``     ``(const uid_r *ruid, const uid_r *euid)``, also
+                   ``setregid_r``
+``setresuid_r``    ``(const uid_r *ruid, const uid_r *euid, const uid_r
+                   *suid)``, also ``setresgid_r``
+``getresuid_r``    ``(uid_r *ruid, uid_r *euid, uid_r *suid)``, also
+                   ``getresgid_r``; ``NULL`` pointers are skipped
+``setfsuid_r``     ``(const uid_r *uid, uid_r *old)``, also
+                   ``setfsgid_r``. Unlike ``setfsuid()`` it fails with
+                   ``EPERM`` instead of silently, and returns the old id
+                   in ``*old``; a ``NULL`` *uid* only queries it.
+``getgroups_r``    ``(int size, gid_r *list)``, returns the number of
+                   groups like ``getgroups()``
+``setgroups_r``    ``(int size, const gid_r *list)``; "no id" is not
+                   allowed in the list
+``chown_r``        ``(const char *path, const uid_r *user, const gid_r
+                   *group)``, also ``lchown_r``, ``fchown_r(int fd, ...)``
+                   and ``fchownat_r(int dfd, const char *path, ..., int
+                   flags)``
+=================  =======================================================
+
+Supplementary groups are sorted by kind (classic, UUID, GUID) and value.
+
+Other interfaces
+================
+
+``statx()``
+	``STATX_UID_R`` and ``STATX_GID_R`` report ``stx_uid_r`` and
+	``stx_gid_r``.
+
+Sockets
+	``SO_PEERCRED_R`` returns a ``struct __kernel_ucred_r`` (pid, uid,
+	gid), ``SO_PEERGROUPS_R`` the peer's groups as ``__kernel_gid_r_t``.
+	``SO_PASSCRED_R`` asks for ``SCM_CREDENTIALS_R`` messages with a
+	``struct __kernel_ucred_r``; they can be sent with the rules of
+	``SCM_CREDENTIALS``. Netlink keeps classic ids in its messages.
+
+Signals
+	``siginfo_t`` has ``si_uid_r``, the sender's uid, at offset 96 in
+	every layout; ``signalfd_siginfo`` has ``ssi_uid_r``. It is
+	``UID_R_NONE`` where the kernel doesn't set it; ``waitid()`` fills it
+	in.
+
+System V IPC
+	``IPC_STAT_R`` and ``IPC_SET_R`` for ``msgctl()``, ``semctl()`` and
+	``shmctl()`` read and set a ``struct ipc_perm_r`` (key, mode, uid,
+	gid, cuid, cgid).
+
+Keys
+	``KEYCTL_CHOWN_R`` takes ``__kernel_uid_r_t`` owner and group.
+
+POSIX ACLs
+	Version 3 of the ACL xattr format (``POSIX_ACL_XATTR_VERSION_R``)
+	has ``struct posix_acl_xattr_entry_r`` entries with an id kind and
+	16 bytes of id. ``getxattr()`` returns version 3 only if an entry is
+	a UUID or GUID; ``setxattr()`` takes both versions.
+
+procfs
+	``/proc/<pid>/status`` has ``Uid_r:``, ``Gid_r:`` and ``Groups_r:``
+	lines with the text form of the ids; ``/proc/<pid>/loginuid`` reads
+	and writes UUIDs and GUIDs as text.
+
+Audit
+	Records show UUIDs and GUIDs in their text form; classic ids are
+	printed as before.
+
+RPCSEC_GSS upcalls
+	The text (v1) upcall to gssd names a UUID or GUID user as
+	``uid_r=<text form>`` instead of ``uid=<number>``; gssd versions that
+	don't know it find no ``uid=`` and refuse the upcall. A downcall for
+	such a user starts with the uid ``-1`` (never valid) followed by the
+	user as ``__kernel_uid_r_t``, then the usual fields. The binary (v0)
+	upcall can't carry such users and fails with ``EACCES``.
+
+Limitations
+===========
+
+- Quotas don't account UUID and GUID owners; quota files hold 32 bit ids.
+- RPCSEC_GSS needs a gssd that knows ``uid_r=`` for UUID and GUID users.
+- UUID and GUID users can't create unprivileged ublk devices.
+- Audit filter rules, SafeSetID policies and IMA policy rules name
+  classic ids only.
-- 
2.56.0




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