User and group ids are 32 bit numbers. Identities that come from
elsewhere -- UUIDs handed out by a directory service, or the GUIDs of a
Windows domain -- have to be squeezed into that range through mapping
tables kept in userspace, and the kernel never sees who a process really
is.
Add a tagged id for a new family of system calls (named after the
classic ones with an _r suffix): a classic 32 bit id, an RFC 9562
version 4 UUID, or a Microsoft GUID in the byte order Windows stores it
in. Type 0 is "no id", so a zero-initialized id is never root, and lets
the set*id_r() calls express "unchanged" without a magic number.
The struct has no 64 bit members and the same layout on all ABIs, so
none of the new calls needs a compat entry point.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jan Koester <redacted>
---
include/uapi/linux/uidgid_r.h | 45 +++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 include/uapi/linux/uidgid_r.h
diff --git a/include/uapi/linux/uidgid_r.h b/include/uapi/linux/uidgid_r.h
new file mode 100644
index 0000000000..c3b1cb2ae2
--- /dev/null
+++ b/include/uapi/linux/uidgid_r.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * User and group ids for the *_r system calls: a classic 32 bit id, a
+ * UUID or a Microsoft GUID.
+ *
+ * The classic system calls (getuid(), chown(), ...) keep their 32 bit
+ * ids; for an id that has no 32 bit form they see the overflow id
+ * (/proc/sys/kernel/overflowuid and overflowgid), like the 16 bit system
+ * calls do for ids above 65535.
+ */
+#ifndef _UAPI_LINUX_UIDGID_R_H
+#define _UAPI_LINUX_UIDGID_R_H
+
+#include <linux/types.h>
+
+/*
+ * Kinds of id (__kernel_uid_r_t.type). An all-zero id is UID_R_NONE, so a
+ * zero-initialized id never stands for root.
+ */
+#define UID_R_NONE 0 /* no id: "unchanged" or "not set" */
+#define UID_R_LEGACY 1 /* classic 32 bit id in .legacy */
+#define UID_R_UUID 2 /* RFC 9562 UUID, version 4, in .uuid */
+#define UID_R_GUID 3 /* Microsoft GUID in .guid */
+
+#define UID_R_SIZE 16 /* bytes of .uuid and .guid */
+
+/*
+ * .uuid holds the UUID in network byte order, as RFC 9562 lays it out.
+ * .guid holds the GUID as Windows stores it: Data1, Data2 and Data3 little
+ * endian, Data4 as is.
+ *
+ * Bytes past the member .type selects are reserved and must be zero.
+ */
+typedef struct __kernel_uid_r {
+ __u32 type;
+ union {
+ __u32 legacy;
+ __u8 uuid[UID_R_SIZE];
+ __u8 guid[UID_R_SIZE];
+ };
+} __kernel_uid_r_t;
+
+typedef __kernel_uid_r_t __kernel_gid_r_t;
+
+#endif /* _UAPI_LINUX_UIDGID_R_H */--
2.56.0