Skip to content

sched/group: add POSIX saved UID/GID APIs and pseudo-fs ownership - #19578

Open
Abhishekmishra2808 wants to merge 6 commits into
apache:masterfrom
Abhishekmishra2808:multiuser
Open

sched/group: add POSIX saved UID/GID APIs and pseudo-fs ownership#19578
Abhishekmishra2808 wants to merge 6 commits into
apache:masterfrom
Abhishekmishra2808:multiuser

Conversation

@Abhishekmishra2808

Copy link
Copy Markdown
Contributor

Summary

  • Add getresuid, getresgid, setreuid, and setregid syscalls
  • Assign inode owner/group at reservation; enforce IPC open permissions
  • Parse NuttX 5-field passwd records in libc
  • Document credential APIs in Documentation/implementation/user_identity.rst

Impact

Adds POSIX saved UID/GID syscalls (getresuid, getresgid, setreuid, setregid) and completes multi-user support for pseudo-FS inode ownership and IPC open permission checks. Extends libc passwd parsing for NuttX 5-field records.
New behavior is gated behind CONFIG_SCHED_USER_IDENTITY and existing CONFIG_FS_PERMISSION options.

Testing

user_main: multi-user test
multiuser_test: start
multiuser: effective UID/GID switching
  PASS: initial uid == 0
  PASS: initial euid == 0
  PASS: initial gid == 0
  PASS: initial egid == 0
  PASS: root seteuid(1000)
  PASS: euid after seteuid(1000) == 1000
  PASS: root seteuid(0) restore
  PASS: euid restored to 0 == 0
  PASS: root setegid(2000)
  PASS: egid after setegid(2000) == 2000
  PASS: root setegid(0) restore
  PASS: egid restored to 0 == 0
multiuser: getresuid/getresgid and setreuid/setregid
  PASS: getresuid(initial)
  PASS: initial real uid == 0
  PASS: initial eff uid == 0
  PASS: initial saved uid == 0
  PASS: getresgid(initial)
  PASS: initial real gid == 0
  PASS: initial eff gid == 0
  PASS: initial saved gid == 0
  PASS: root setreuid(-1,1000)
  PASS: real uid after setreuid(-1,1000) == 0
  PASS: eff uid after setreuid(-1,1000) == 1000
  PASS: saved uid after setreuid(-1,1000) == 1000
  PASS: non-root setreuid(2000,-1) denied errno=1
  PASS: setreuid(-1,0) drop effective
  PASS: root setreuid(0,-1) restore
  PASS: real uid restored == 0
  PASS: eff uid restored == 0
  PASS: saved uid restored == 0
  PASS: root setregid(-1,1000)
  PASS: real gid after setregid(-1,1000) == 0
  PASS: eff gid after setregid(-1,1000) == 1000
  PASS: saved gid after setregid(-1,1000) == 1000
  PASS: non-root setregid(2000,-1) denied errno=1
  PASS: setregid(-1,0) drop effective
  PASS: root setregid(0,-1) restore
multiuser: setreuid(1000,1000) full assignment (child task)
  PASS: root setreuid(1000,1000)
  PASS: getresuid(after setreuid)
  PASS: real uid after setreuid == 1000
  PASS: eff uid after setreuid == 1000
  PASS: saved uid after setreuid == 1000
multiuser_resuid_child: 0 failure(s)
  PASS: mu_resuid child completed successfully
  PASS: parent euid after resuid child == 0
  PASS: parent egid after resuid child == 0
multiuser: saved set-UID/GID semantics (child task)
multiuser_suid_child: saved set-UID/GID semantics
  PASS: setuid(1000) as root
  PASS: uid after setuid(1000) == 1000
  PASS: euid after setuid(1000) == 1000
  PASS: non-root seteuid(0) denied errno=1
  PASS: euid unchanged after denied seteuid(0) == 1000
  PASS: non-root seteuid(1000)
  PASS: root-group setegid(2000)
  PASS: egid after setegid(2000) == 2000
  PASS: root-group setegid(0) restore
  PASS: setgid(3000)
  PASS: gid after setgid(3000) == 3000
  PASS: egid after setgid(3000) == 3000
  PASS: non-root setegid(0) denied errno=1
  PASS: egid unchanged after denied setegid(0) == 3000
multiuser_suid_child: 0 failure(s)
  PASS: mu_suid child completed successfully
  PASS: parent euid after child == 0
  PASS: parent egid after child == 0
multiuser: pseudoFS chmod/chown/open permissions
  PASS: /ostest_mu_perm owner 0:0
  PASS: root chmod(0600)
  PASS: non-owner chmod(0777) denied errno=1
  PASS: non-root chown(0,0) denied errno=1
  PASS: root chown to 1000:1000
  PASS: /ostest_mu_perm owner 1000:1000
  PASS: owner chmod(0777)
  PASS: /ostest_mu_secret owner 0:0
  PASS: open(/ostest_mu_secret) denied with EACCES
  PASS: open(/ostest_mu_secret) allowed
  PASS: /ostest_mu_user owner 1000:1000
  PASS: open(/ostest_mu_user) allowed
multiuser: tmpfs open permission enforcement
  PASS: /tmp/ostest_mu_secret owner 0:0
  PASS: open(/tmp/ostest_mu_secret) denied with EACCES
  PASS: open(/tmp/ostest_mu_secret) allowed
multiuser: message queue ownership and permissions
  PASS: /var/mqueue/ostest_mu_mq owner 1000:1000
  PASS: /var/mqueue/ostest_mu_mq mode 0600
  PASS: mq_open(other user) denied errno=13
  PASS: mq_open(owner)
multiuser: named semaphore ownership and permissions
  PASS: /var/sem/ostest_mu_sem owner 1000:1000
  PASS: sem_open(other user) denied errno=13
  PASS: sem_open(owner)
multiuser: shared memory ownership and permissions
  PASS: /var/shm/ostest_mu_shm owner 1000:1000
  PASS: shm_open(other user) denied errno=13
  PASS: shm_open(owner)
multiuser: FIFO ownership and permissions
  PASS: /ostest_mu_fifo owner 1000:1000
  PASS: open fifo (other user) denied errno=13
  PASS: open fifo (owner)
multiuser: passwd lookup after credential drop
  PASS: installed /tmp/ostest_passwd
  PASS: getpwnam(root) uid=0
  PASS: getpwnam(testuser) uid=1000
multiuser_test: 0 failure(s)

Comment thread libs/libc/unistd/lib_getresgid.c
@github-actions github-actions Bot added Area: Documentation Improvements or additions to documentation Size: L The size of the change in this PR is large labels Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

arduino-mega2560

  • flash: .text +12 B (+0.0%, 67,430 B / 262,144 B, total: 26% used)

hifive1-revb

  • flash: .text +8 B (+0.0%, 83,352 B / 4,194,304 B, total: 2% used)

mirtoo

  • kseg0_progmem: .text +24 B (+0.0%, 67,436 B / 131,072 B, total: 51% used)

qemu-armv8a

  • Code: .text.file_mq_vopen +40 B, .text.inode_checkopenperm +8 B (+0.0%, 318,122 B)

qemu-intel64

  • Code: .text +72 B (+0.0%, 8,658,048 B)

s698pm-dkit

  • Code: .text +80 B (+0.0%, 363,248 B)

stm32-nucleo-f103rb

  • flash: .text +4 B (+0.0%, 33,928 B / 131,072 B, total: 26% used)
    No memory changes detected for:
  • esp32-devkitc
  • rx65n-rsk2mb

acassis
acassis previously approved these changes Jul 29, 2026
Comment thread include/unistd.h Outdated
Comment thread fs/inode/fs_inodereserve.c Outdated
Comment thread fs/inode/fs_inode.c Outdated
Implement POSIX real/effective/saved credential getters and paired
setters in the task group layer, with libc stubs and syscalls.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Set i_owner and i_group from the caller's effective credentials in
inode_reserve(), covering IPC objects, FIFOs, and pseudo-files.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Use inode_checkopenperm() for message queues, named semaphores, and
shm, and reallocate mqueue state when reopening after the last close.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Accept user:hash:uid:gid:home lines produced by mkpasswd in addition
to the six-field gecos form, and raise the default line buffer to 256.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Document setreuid/setregid, getresuid/getresgid, and how inode_reserve
assigns owner and group for pseudo-filesystem objects.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
When CONFIG_TESTING_OSTEST_MULTIUSER is enabled, default
CONFIG_LIBC_PASSWD_FILEPATH to a writable tmpfs path used by the
ostest multiuser passwd sub-test.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

After merging this, please re-run the CI at apache/nuttx-apps#3677

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Documentation Improvements or additions to documentation Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants