xiaoxiang781216 commented on code in PR #19767:
URL: https://github.com/apache/nuttx/pull/19767#discussion_r3763871786
##########
include/sys/prctl.h:
##########
@@ -79,6 +79,20 @@
#define PR_SET_DUMPABLE 5
#define PR_GET_DUMPABLE 6
+/* PR_NSHCRED_ENABLE — set GROUP_FLAG_NSHCRED on this task group.
+ * Requires euid == 0. Not inherited by child task groups.
+ * Required for PR_NSHCRED_AUTHSETEID.
+ *
+ * PR_NSHCRED_AUTHSETEID — verify username/password against the passwd
Review Comment:
Here is how Linux implement `sudo`, it's better to implement by the similar
approach:
`sudo` is a **userspace program**, not a kernel feature — the kernel
provides two primitives, and sudo combines them with policy logic.
## 1. The kernel primitive: setuid bit + `execve`
The core mechanism is the **set-user-ID (setuid)** permission bit on the
executable file:
```bash
$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root /usr/bin/sudo # note the 's'
```
When the kernel's `execve()` loads an executable with the setuid bit set, it
changes the new process's **effective UID to the file's owner** (root, UID 0)
instead of the caller's UID. This logic lives in the kernel's binary-format
loader — see exec.c (`bprm_fill_uid` in `prepare_binprm()`) and the
`suser`/`capable` checks in capability.c.
So: `sudo` itself starts running as **root** the moment it executes,
regardless of who invoked it. The caller's identity is preserved via the **real
UID**, which remains the invoking user.
## 2. sudo's userspace logic
Running as root, sudo then:
1. **Identifies the caller** — from the real UID (`getuid()`), resolving to
a username via passwd.
2. **Checks policy** — parses sudoers (and sudoers.d) to decide whether this
user/group may run this command on this host as that target user. sudoers
syntax is compiled to minimize injection risks; it's opened with
`SUDOERS_NOEXEC` protections.
3. **Authenticates** — usually via **PAM** (`pam_authenticate()`), prompting
for the *caller's* password. A successful auth is cached in a timestamp file
under ts (default 15 min), so repeated invocations skip the password.
4. **Sets up the environment** — sanitizes env vars (keeps only a whitelist
like `TERM`, `PATH` reset to `secure_path`), sets `SUDO_USER`, working
directory, resource limits, SELinux context, etc.
5. **Drops to the target identity** — calls `setresuid()`/`setresgid()`
(typically to root, or another user with `sudo -u`), plus `setgroups()`. Now
the privileges are *permanently* that of the target user.
6. **`execve()`s the requested command**, replacing itself.
## 3. Why the design is safe
- The **kernel enforces** the privilege transition: only setuid-root
binaries can elevate; arbitrary processes can't `setuid(0)` unless already root.
- The **policy and password check happen while sudo is root**, so an
unprivileged user cannot forge them.
- Modern kernels further restrict this via **capabilities** (capability.h)
and LSM hooks (SELinux/AppArmor) — `execve` on a setuid binary goes through
`security_bprm_creds_from_file()` in security.c.
## Minimal reproduction
```c
/* minisudo.c — gcc -o minisudo minisudo.c && sudo chown root minisudo &&
sudo chmod u+s minisudo */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
printf("ruid=%d euid=%d\n", getuid(), geteuid()); /* ruid=you, euid=0 */
setresuid(0, 0, 0); /* become fully root
*/
execvp(argv[1], &argv[1]); /* run the command */
perror("execvp");
return 1;
}
```
This is the entire privilege mechanism in ~10 lines. Real sudo adds ~100k
lines for policy parsing, PAM auth, auditing, I/O logging, and attack-surface
hardening — but the kernel side is just: **setuid bit on `execve` +
`setresuid`**.
Alternatives that avoid setuid entirely: `su` (same setuid trick), `doas`
(OpenBSD's simpler sudo), `polkit`/`systemd-run` (root daemon does the work via
IPC), and user-namespace-based tools.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]