All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.