mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH 00/41] UUID and GUID user and group ids (*_r system calls)
@ 2026-10-18 18:01 Jan Koester
  2026-10-18 18:01 ` [RFC PATCH 01/41] uuid: move uuid_t and guid_t into <linux/uuid_types.h> Jan Koester
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Jan Koester @ 2026-10-18 18:01 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, Serge E. Hallyn
  Cc: Jan Kara, Theodore Y. Ts'o, Paul Moore, Arnd Bergmann,
	linux-fsdevel, linux-api, linux-security-module, linux-arch,
	linux-ext4, linux-nfs, linux-cifs, netdev, audit, keyrings,
	linux-kernel

Hi,

this RFC series lets a user or group id be a UUID (RFC 9562, version 4)
or a Microsoft GUID as well as a classic 32-bit number. Processes can run
as such a user, files can be owned by one, and credentials, ACLs, keys,
System V IPC, sockets, signals, audit and procfs carry the whole id.

Why
---
Directory services name users by 128-bit ids: Active Directory by
objectGUID (and SIDs), LDAP directories often by entryUUID. Today every
system that serves such users (winbind, sssd, nfsidmap, ksmbd user
space) maps them to 32-bit numbers through ranges, hashes or a local
database. The numbers differ between machines unless the mapping is
configured the same everywhere, mappings can collide, and ownership
written to shared storage or a backup depends on the machine that wrote
it. With the 128-bit id in the kernel, the id the directory hands out is
also the owner on disk and in every credential, and no mapping table is
needed.

Design
------
- kuid_t and kgid_t become a tagged union (legacy number, UUID, GUID)
  instead of a u32. There is no table that maps UUIDs to numbers: the
  kernel compares, hashes and stores the whole id. uid_eq(), uid_lt()
  and the other helpers keep their meaning. Patches 1-3 add the UAPI
  type and helpers. Patches 4-8 fix places that relied on kuid_t being
  a u32: sk_uid is now read through a seqcount, and af_unix, netlink and
  Bluetooth keep only classic ids in skb->cb. Patch 9 changes the type.

- UUIDs and GUIDs exist only in the initial user namespace. They are not
  part of any uid_map or gid_map, show as the overflow id in other
  namespaces, and no capability in a child namespace gives privilege
  over them. Idmapped mounts pass them through unchanged.

- The classic system calls keep their 32-bit ids and show a UUID or GUID
  as the overflow id, as the 16-bit calls do for ids above 65535. A new
  family, named after the old calls with an _r suffix (getuid_r,
  setresuid_r, setgroups_r, fchownat_r, ...), takes a 20-byte
  __kernel_uid_r_t:

	typedef struct __kernel_uid_r {
		__u32 type;	/* UID_R_NONE, _LEGACY, _UUID, _GUID */
		union {
			__u32 legacy;
			__u8 uuid[16];
			__u8 guid[16];
		};
	} __kernel_uid_r_t;

  It has the same layout on every ABI, so none of the calls needs a
  compat entry.

- Existing interfaces get _R variants where an id is in the ABI:
  STATX_UID_R/STATX_GID_R, SO_PEERCRED_R, SO_PEERGROUPS_R,
  SCM_CREDENTIALS_R, si_uid_r in siginfo (offset 96 in every layout),
  IPC_STAT_R/IPC_SET_R, KEYCTL_CHOWN_R, and version 3 of the POSIX ACL
  xattr. procfs, audit records, key descriptions and the RPCSEC_GSS
  upcall use a text form (decimal, UUID, or GUID in braces).

- A filesystem has to declare that it can store such owners
  (SB_I_UID_R). Everywhere else, chown and creating a file as such a
  user fail with EOVERFLOW, so a UUID never turns into a wrong number
  on disk. tmpfs, ramfs and devpts declare it, overlayfs does when its
  upper layer does, and ext4 does with a new read-only compatible
  feature, uid_r (patches 31, 32 and 34; 256-byte inodes). NFSv4 and
  ksmbd carry the ids as text or as SIDs (S-1-22-3/4/5/6-...).

- Things that can't carry a 128-bit id fail closed instead of mapping:
  quotas don't account such owners, AUTH_SYS sends the overflow id,
  unprivileged ublk devices are refused, and gssd versions that don't
  know uid_r= refuse the upcall.

Documentation/userspace-api/uid_r.rst (patches 35 and 41) describes the
whole ABI and its limitations.

Testing
-------
- tools/testing/selftests/uid_r (patch 36): 14/14 pass.
- A boot test suite (nolibc init on QEMU, ext4 images with and without
  uid_r): 88/88 pass, on a kernel with USER_NS, overlayfs, tmpfs, POSIX
  ACLs and audit enabled.
- End to end on a full distribution (FenrirOS: patched libc, e2fsprogs,
  OpenSSH, rsync, libarchive, a ksmbd and NFS server): UUID users log in
  over ssh, own files on ext4, and reach ksmbd and NFSv4 shares.
- The runtime tests above ran on the same series on top of v7.2.9 and
  v7.2.11. On v7.3-rc7, the series has so far been built for x86_64
  (bzImage and modules, with USER_NS, audit, ecryptfs, fscrypt, quota,
  ublk, NFS, Bluetooth and the LSMs enabled), not yet booted.
- The syscall tables of the other architectures are wired up (patch 22)
  but haven't been built.

The e2fsprogs changes (mke2fs/tune2fs -O uid_r, e2fsck, debugfs, ACL
conversion in libext2fs) will be sent to linux-ext4 separately.

Open questions
--------------
- Is a tagged union in kuid_t acceptable, or would you rather see the
  128-bit id kept beside a u32 kuid_t?
- The new calls copy the classic get/set*id() and chown() families
  one by one (20 entries). A single setid_r(which, ...) call would need
  fewer syscall numbers. Which do you prefer?
- Should the series be split per subsystem (core/uidgid, fs and VFS,
  net, ext4, nfsd/ksmbd) after this RFC?

The series is based on v7.3-rc7. The syscall numbers (473-492 on most
architectures) are placeholders and will follow whatever is merged first.

Jan Koester (41):
  uuid: move uuid_t and guid_t into <linux/uuid_types.h>
  uapi: add <linux/uidgid_r.h> for 128 bit capable user and group ids
  uidgid: add uid_is_legacy() and gid_is_legacy()
  net: sock: read sk_uid through a seqcount
  af_unix: keep sender ids in skb->cb only when they are classic ids
  netlink: keep classic sender ids in skb->cb
  Bluetooth: keep classic sender ids in skb->cb
  smb: client: use __kuid_val() for the unix SIDs of the caller
  uidgid: let kuid_t and kgid_t hold a UUID or a GUID
  uidgid: convert between kernel ids and the ids of the *_r system calls
  fscrypt: show the whole uid in the description of user key claims
  keys: name per-user keyrings of UUID and GUID users by the whole uid
  ublk: refuse unprivileged devices to UUID and GUID users
  nfsd: don't hand out uid 0 for read layouts of UUID-owned files
  SUNRPC: name UUID and GUID users to gssd as uid_r=
  ecryptfs: hash daemons by kuid_hash()
  quota: don't account UUID and GUID owners
  fs: keep UUID and GUID owners off filesystems that can't store them
  cred: add the *_r variants of the get/set*id() system calls
  groups: add getgroups_r() and setgroups_r()
  fs: add chown_r(), lchown_r(), fchown_r() and fchownat_r()
  arch: wire up the *_r uid and gid system calls
  statx: report UUID and GUID owners
  shmem, ramfs: allow UUID and GUID owners
  uidgid: parse and print ids in their text form
  proc: show UUID and GUID ids in status, accept them for loginuid
  audit: log UUID and GUID ids in full
  net: add SO_PEERCRED_R, SO_PEERGROUPS_R and SCM_CREDENTIALS_R
  signal: report the sender's UUID or GUID uid in si_uid_r
  ipc: add IPC_STAT_R and IPC_SET_R
  ext4: add the uid_r feature for UUID and GUID owners
  ext4: let uid_r be turned on while the filesystem is mounted
  posix_acl: support UUID and GUID entries
  ext4: store ACLs with UUID and GUID entries on uid_r filesystems
  Documentation: describe UUID and GUID user and group ids
  selftests: add tests for UUID and GUID ids
  ovl: allow UUID and GUID owners when the upper layer does
  devpts: allow UUID and GUID owners
  ksmbd: log in UUID and GUID users and map them to SIDs
  nfsd, nfs: carry UUID and GUID owners as their text form
  Documentation: uid_r: describe SMB and NFSv4

 Documentation/userspace-api/index.rst       |   1 +
 Documentation/userspace-api/uid_r.rst       | 186 +++++++
 arch/alpha/include/uapi/asm/socket.h        |   5 +
 arch/alpha/kernel/syscalls/syscall.tbl      |  20 +
 arch/arm/tools/syscall.tbl                  |  20 +
 arch/arm64/tools/syscall_32.tbl             |  20 +
 arch/m68k/kernel/syscalls/syscall.tbl       |  20 +
 arch/microblaze/kernel/syscalls/syscall.tbl |  20 +
 arch/mips/include/uapi/asm/socket.h         |   5 +
 arch/mips/kernel/syscalls/syscall_n32.tbl   |  20 +
 arch/mips/kernel/syscalls/syscall_n64.tbl   |  20 +
 arch/mips/kernel/syscalls/syscall_o32.tbl   |  20 +
 arch/parisc/include/uapi/asm/socket.h       |   5 +
 arch/parisc/kernel/syscalls/syscall.tbl     |  20 +
 arch/powerpc/kernel/syscalls/syscall.tbl    |  20 +
 arch/s390/kernel/syscalls/syscall.tbl       |  20 +
 arch/sh/kernel/syscalls/syscall.tbl         |  20 +
 arch/sparc/include/uapi/asm/socket.h        |   5 +
 arch/sparc/kernel/syscalls/syscall.tbl      |  20 +
 arch/x86/entry/syscalls/syscall_32.tbl      |  20 +
 arch/x86/entry/syscalls/syscall_64.tbl      |  20 +
 arch/xtensa/kernel/syscalls/syscall.tbl     |  20 +
 drivers/block/ublk_drv.c                    |  17 +-
 drivers/tty/tty_audit.c                     |   7 +-
 fs/attr.c                                   |   7 +
 fs/crypto/keyring.c                         |   7 +-
 fs/devpts/inode.c                           |   2 +
 fs/ecryptfs/messaging.c                     |   2 +-
 fs/ext4/acl.c                               | 109 +++-
 fs/ext4/acl.h                               |  34 +-
 fs/ext4/ext4.h                              |  27 +-
 fs/ext4/inode.c                             | 115 ++++-
 fs/ext4/ioctl.c                             |  30 +-
 fs/ext4/super.c                             |  45 +-
 fs/mnt_idmapping.c                          |  14 +
 fs/nfs/nfs4idmap.c                          |  53 ++
 fs/nfs/super.c                              |   2 +
 fs/nfsd/flexfilelayout.c                    |   6 +-
 fs/nfsd/nfs4idmap.c                         |  68 ++-
 fs/open.c                                   | 144 +++++-
 fs/overlayfs/super.c                        |   3 +
 fs/posix_acl.c                              | 123 ++++-
 fs/proc/array.c                             |  17 +-
 fs/proc/base.c                              |  38 +-
 fs/quota/dquot.c                            |   3 +
 fs/ramfs/inode.c                            |   1 +
 fs/signalfd.c                               |   3 +
 fs/smb/client/cifsacl.c                     |   2 +-
 fs/smb/client/smb2pdu.c                     |   7 +-
 fs/smb/server/ksmbd_netlink.h               |  15 +-
 fs/smb/server/mgmt/user_config.c            |  35 +-
 fs/smb/server/mgmt/user_config.h            |   4 +-
 fs/smb/server/smb2pdu.c                     |  10 +-
 fs/smb/server/smb_common.c                  |  18 +-
 fs/smb/server/smbacl.c                      | 178 +++++--
 fs/smb/server/smbacl.h                      |  19 +-
 fs/smb/server/transport_ipc.c               |   4 +-
 fs/smb/server/vfs_cache.c                   |   9 +-
 fs/smb/server/vfs_cache.h                   |   4 +-
 fs/stat.c                                   |  24 +-
 include/linux/audit.h                       |   8 +-
 include/linux/compat.h                      |   6 +
 include/linux/fs.h                          |  29 +-
 include/linux/fs/super_types.h              |   1 +
 include/linux/mnt_idmapping.h               |  74 ++-
 include/linux/netlink.h                     |   2 +-
 include/linux/posix_acl_xattr.h             |  31 ++
 include/linux/ptrace.h                      |   2 +-
 include/linux/quota.h                       |  18 +
 include/linux/signal.h                      |  22 +
 include/linux/signal_types.h                |   5 +-
 include/linux/socket.h                      |   1 +
 include/linux/syscalls.h                    |  44 ++
 include/linux/uidgid.h                      | 165 +++++-
 include/linux/uidgid_types.h                |  32 +-
 include/linux/uuid.h                        |  11 +-
 include/linux/uuid_types.h                  |  21 +
 include/net/bluetooth/bluetooth.h           |   2 +-
 include/net/scm.h                           |  28 +
 include/net/sock.h                          |  32 +-
 include/uapi/asm-generic/siginfo.h          |  17 +
 include/uapi/asm-generic/socket.h           |   5 +
 include/uapi/asm-generic/unistd.h           |  43 +-
 include/uapi/linux/ipc.h                    |  17 +
 include/uapi/linux/keyctl.h                 |   1 +
 include/uapi/linux/posix_acl_xattr.h        |  19 +
 include/uapi/linux/signalfd.h               |   4 +-
 include/uapi/linux/socket.h                 |   9 +
 include/uapi/linux/stat.h                   |  10 +-
 include/uapi/linux/uidgid_r.h               |  45 ++
 io_uring/waitid.c                           |  32 +-
 io_uring/waitid.h                           |   1 +
 ipc/mqueue.c                                |   4 +-
 ipc/msg.c                                   |  40 +-
 ipc/sem.c                                   |  31 +-
 ipc/shm.c                                   |  32 +-
 ipc/util.c                                  | 112 +++-
 ipc/util.h                                  |  23 +-
 kernel/Makefile                             |   1 +
 kernel/audit.c                              |  50 +-
 kernel/audit.h                              |   4 +-
 kernel/auditsc.c                            |  63 ++-
 kernel/exit.c                               |  18 +-
 kernel/exit.h                               |   3 +
 kernel/groups.c                             |  94 +++-
 kernel/signal.c                             |  48 +-
 kernel/sys.c                                | 472 ++++++++++++-----
 kernel/sys_ni.c                             |  12 +
 kernel/ucount.c                             |   2 +-
 kernel/uidgid_r.c                           | 467 +++++++++++++++++
 kernel/user.c                               |   2 +-
 kernel/user_namespace.c                     |  10 +-
 lib/kobject_uevent.c                        |   8 +-
 mm/oom_kill.c                               |   2 +-
 mm/shmem.c                                  |   2 +
 net/bluetooth/hci_sock.c                    |   8 +-
 net/core/dev.c                              |   8 +-
 net/core/scm.c                              |  94 ++--
 net/core/sock.c                             |  90 +++-
 net/netlabel/netlabel_user.c                |   4 +-
 net/netlink/af_netlink.c                    |   4 +-
 net/socket.c                                |   5 +-
 net/sunrpc/auth_gss/auth_gss.c              |  44 +-
 net/unix/af_unix.c                          |  53 +-
 net/unix/af_unix.h                          |  11 +-
 scripts/syscall.tbl                         |  20 +
 security/apparmor/file.c                    |   8 +-
 security/integrity/ima/ima_policy.c         |   8 +-
 security/integrity/integrity_audit.c        |   6 +-
 security/ipe/audit.c                        |  12 +-
 security/keys/compat.c                      |   3 +
 security/keys/internal.h                    |   3 +
 security/keys/keyctl.c                      |  61 ++-
 security/keys/persistent.c                  |  11 +-
 security/keys/process_keys.c                |  36 +-
 security/keys/request_key.c                 |  12 +-
 security/selinux/selinuxfs.c                |   8 +-
 security/selinux/ss/services.c              |   4 +-
 tools/testing/selftests/Makefile            |   1 +
 tools/testing/selftests/uid_r/.gitignore    |   1 +
 tools/testing/selftests/uid_r/Makefile      |   6 +
 tools/testing/selftests/uid_r/config        |   4 +
 tools/testing/selftests/uid_r/uid_r_test.c  | 535 ++++++++++++++++++++
 143 files changed, 4425 insertions(+), 605 deletions(-)
 create mode 100644 Documentation/userspace-api/uid_r.rst
 create mode 100644 include/linux/uuid_types.h
 create mode 100644 include/uapi/linux/uidgid_r.h
 create mode 100644 kernel/uidgid_r.c
 create mode 100644 tools/testing/selftests/uid_r/.gitignore
 create mode 100644 tools/testing/selftests/uid_r/Makefile
 create mode 100644 tools/testing/selftests/uid_r/config
 create mode 100644 tools/testing/selftests/uid_r/uid_r_test.c


base-commit: 32c52ec87d6245ee2d12ed5dd509e40062939b50
-- 
2.56.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-10-19  2:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-18 18:01 [RFC PATCH 00/41] UUID and GUID user and group ids (*_r system calls) Jan Koester
2026-10-18 18:01 ` [RFC PATCH 01/41] uuid: move uuid_t and guid_t into <linux/uuid_types.h> Jan Koester
2026-10-18 18:01 ` [RFC PATCH 02/41] uapi: add <linux/uidgid_r.h> for 128 bit capable user and group ids Jan Koester
2026-10-18 18:01 ` [RFC PATCH 03/41] uidgid: add uid_is_legacy() and gid_is_legacy() Jan Koester
2026-10-18 18:01 ` [RFC PATCH 04/41] net: sock: read sk_uid through a seqcount Jan Koester
2026-10-18 18:01 ` [RFC PATCH 05/41] af_unix: keep sender ids in skb->cb only when they are classic ids Jan Koester
2026-10-18 18:01 ` [RFC PATCH 06/41] netlink: keep classic sender ids in skb->cb Jan Koester
2026-10-18 18:01 ` [RFC PATCH 07/41] Bluetooth: " Jan Koester
2026-10-18 18:01 ` [RFC PATCH 08/41] smb: client: use __kuid_val() for the unix SIDs of the caller Jan Koester
2026-10-18 18:01 ` [RFC PATCH 09/41] uidgid: let kuid_t and kgid_t hold a UUID or a GUID Jan Koester
2026-10-18 19:47   ` Andy Lutomirski
2026-10-18 21:02   ` Eric Biggers
2026-10-19  2:10     ` Jan Koester
2026-10-18 18:01 ` [RFC PATCH 10/41] uidgid: convert between kernel ids and the ids of the *_r system calls Jan Koester
2026-10-18 18:01 ` [RFC PATCH 11/41] fscrypt: show the whole uid in the description of user key claims Jan Koester

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®