Skip to content

sched: supplementary groups, setresuid/setresgid, and PR_NSHCRED_AUTHSETEID - #19767

Open
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:feature/supp-groups-and-sudo
Open

sched: supplementary groups, setresuid/setresgid, and PR_NSHCRED_AUTHSETEID#19767
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:feature/supp-groups-and-sudo

Conversation

@Abhishekmishra2808

Copy link
Copy Markdown
Contributor

Summary

  • Add per-task-group supplementary GIDs (setgroups / getgroups / initgroups) and honor them in DAC checks.
  • Add setresuid / setresgid for hard and soft credential drop.
  • Add PR_NSHCRED_ENABLE and atomic PR_NSHCRED_AUTHSETEID (passwd verify + raise euid/egid in one prctl).
  • Document the identity model and NSH login / su / sudo behavior.

Impact

This extends NuttX process credentials with supplementary groups and full setres* support, and adds an in-kernel password-authenticated path to raise effective IDs for hard-dropped NSH sessions. Boards that enable CONFIG_SCHED_USER_IDENTITY (and related passwd/crypto options for AUTHSETEID) get the new syscalls and prctl commands; default configs that leave user identity disabled are unchanged.

Testing

nsh# useradd testuser UserPass1!
nsh# cat /tmp/passwd
root:$pbkdf2-sha256$10000$uwK3GNfobksYkqa5H9-Rcw$kNsxMZi26PeLxdWKgFjNvZpOoouP_DcHyO2mwyACVc0:0:0:/
testuser:$pbkdf2-sha256$10000$LCsDACzp0RA26xvaHPsY2g$gfCJXfLINNOKNIpVqepoUaYJiMbB8ojezAlosZJnrXY:1000:1000:/
nsh# su testuser
nsh$ id
uid=1000(testuser) suid=0(root) gid=1000 sgid=0(root) groups=1000
nsh$ su root
password: 
nsh# id
uid=0(root) gid=0(root) groups=0(root)
nsh# 

@github-actions github-actions Bot added Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. Area: BINFMT labels Aug 10, 2026
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the feature/supp-groups-and-sudo branch from 6602cf8 to f3e8f00 Compare August 10, 2026 16:08
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

#if CONFIG_SCHED_NGROUPS > 0
for (i = 0; i < size; i++)
{
if ((uint16_t)list[i] > INT16_MAX)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add this check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matches existing UID/GID APIs

Comment thread sched/group/group_getgroups.c Outdated
rgroup = rtcb->group;
DEBUGASSERT(rgroup != NULL);

#if CONFIG_SCHED_NGROUPS > 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we move the code related to CONFIG_SCHED_NGROUPS == 0 to libc?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, done

Comment thread sched/group/group_setgroups.c Outdated
}

rgroup->tg_ngroups = size;
#else

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the dummy code to libc too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread binfmt/binfmt_checkexec.c Outdated
int binfmt_checkexecperm(FAR struct binary_s *bin)
{
FAR struct tcb_s *rtcb;
FAR struct task_group_s *tgroup;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rgroup or group

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread fs/inode/fs_inode.c Outdated
int fs_checkmode(uid_t owner, gid_t group, mode_t mode, int amode)
{
FAR struct tcb_s *rtcb;
FAR struct task_group_s *tgroup;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment thread include/nuttx/sched.h
#define GROUP_FLAG_SECURE_EXEC (1 << 5) /* Bit 5: Secure (setuid/setgid) executable */
#define GROUP_FLAG_DUMPABLE (1 << 6) /* Bit 6: Process may be traced / coredumped */
/* Bit 7: Available */
#define GROUP_FLAG_NSHCRED (1 << 7) /* Bit 7: NSH credential agent (login/su) */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where use this flag

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set by PR_NSHCRED_ENABLE, required by AUTHSETEID.

gid_t new_egid;
gid_t new_sgid;

if ((rgid != (gid_t)-1 && (uint16_t)rgid > INT16_MAX) ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why limit to INT16_MAX

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matches existing UID/GID APIs

uid_t new_euid;
uid_t new_suid;

if ((ruid != (uid_t)-1 && (uint16_t)ruid > INT16_MAX) ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

return -EPERM;
}

if ((uint16_t)euid > INT16_MAX || (uint16_t)egid > INT16_MAX)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment thread include/sys/prctl.h
* Requires euid == 0. Not inherited by child task groups.
* Required for PR_NSHCRED_AUTHSETEID.
*
* PR_NSHCRED_AUTHSETEID — verify username/password against the passwd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but why move the verify into kernel? it's better to keep it in userspace

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After hard-drop, raise needs a privileged API. If that API only checks an agent flag (old TOKEN), userspace can skip verify and still raise. AUTHSETEID binds verify and raise together for that reason (on flat builds with no memory isolation).

Soft-drop / saved UIDs avoids kernel passwd checks, but then raise-after-hard-drop goes away.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you prefer keeping atomic kernel verify for hard-drop, or dropping hard-drop and using soft-drop only?

Track supplementary GIDs per task group, wire setgroups/getgroups
syscalls when CONFIG_SCHED_NGROUPS > 0, and honor them in DAC checks
via nxsched_has_gid().  When NGROUPS is 0, libc provides getgroups/
setgroups stubs.  initgroups() fails instead of silently truncating
when membership exceeds CONFIG_SCHED_NGROUPS.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Complete the POSIX credential setters for real/effective/saved UID and
GID so login and privilege-drop paths can clear saved-root without
relying on setreuid patterns alone.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Collapse password verification and euid/egid raise into one in-kernel
prctl so hard-dropped NSH agents cannot mint privilege without the
correct password. This replaces an earlier TOKEN+SETEID split that
allowed mint-without-verify inside a flat address space.

PR_NSHCRED_ENABLE still marks the agent task group at trusted init;
AUTHSETEID requires that flag and a matching PBKDF2 passwd hash.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Document hard/soft drop, setresuid/setresgid, and PR_NSHCRED_AUTHSETEID
for NSH login, su, and sudo.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the feature/supp-groups-and-sudo branch from 0fc9c1b to b569903 Compare August 11, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: BINFMT Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants