Fact-checked by Grok 2 weeks ago

setuid

In Unix-like operating systems, the setuid (set user ID) bit is a special file permission that, when set on an executable file, causes any process executing that file to run with the effective user ID of the file's owner rather than the real user ID of the invoking user. This allows programs to perform privileged operations on behalf of unprivileged users, such as modifying system files or accessing restricted resources, without requiring the user to have ongoing elevated privileges. The setuid mechanism is distinct from standard read, write, and execute permissions and is part of the file's mode bits stored in the inode. When the setuid bit is enabled, it is visually indicated in the long listing output of the command by an 's' in the owner's execute permission position (e.g., -rwsr-xr-x for a file owned by ). For the bit to function, the file must also have execute permissions for the relevant users or groups; if execute is absent, the 's' appears as a capital 'S' but the setuid effect does not activate. The effective user ID change applies only during execution and reverts afterward unless explicitly managed by the program using system calls like setuid(). This behavior is defined in standards and implemented consistently across systems like , , and BSD variants, though some details (e.g., handling on non-executable files) may be implementation-defined. The setuid bit is set or cleared using the command, either symbolically (e.g., chmod u+s filename to enable it for the ) or numerically by adding 4 to the permission mode (e.g., chmod 4755 filename for owner read/write/execute, group/other read/execute, plus setuid). Only the file owner or a privileged (typically ) can modify these special bits. On directories, the setuid bit has no standard effect in and is typically ignored by implementations. Common uses of setuid include utilities that require temporary root privileges, such as /usr/bin/[passwd](/page/Passwd) (which updates shadow password files) or /usr/bin/[sudo](/page/Sudo) (which escalates privileges for authorized commands). These programs are owned by and have the setuid bit set, allowing ordinary users to perform administrative tasks securely. However, setuid should only be applied to trusted, executables, as it does not work reliably on scripts due to restrictions in most kernels. Despite its utility, the setuid bit poses significant security risks if misapplied, as it can enable vulnerabilities if the executable contains bugs or is replaced by . System administrators are advised to audit setuid files regularly (e.g., using find / -perm -4000) and minimize their use, preferring alternatives like or capabilities for finer-grained privilege control. Historical exploits, such as those in misconfigured setuid programs, have led to widespread compromises, underscoring the need for careful implementation.

Permission Bits in Unix-like Systems

Standard File Permissions

In Unix-like operating systems, file permissions follow a standard nine-bit model that controls access based on user categories and operation types. This model divides permissions into three categories—owner (the user who owns the file), group (users in the file's associated group), and other (all remaining users)—with each category assigned three bits representing read (r), write (w), and execute (x) permissions, respectively. The read permission allows viewing file contents or listing directory contents, write enables modification or deletion, and execute permits running files as programs or accessing directory contents. Permissions are commonly represented in symbolic notation, such as rw-r--r--, where the first group of three characters applies to the owner, the second to the group, and the third to others; dashes indicate absent permissions. Equivalently, notation uses three digits (one per category) from 0 to 7, where each digit sums the binary values of the bits: 4 for read, 2 for write, and 1 for execute (e.g., 644 corresponds to rw-r--r--, granting read/write to the owner and read-only to group and others). The command modifies these permissions, accepting either or modes to add, remove, or set bits for specified categories. For instance, chmod 755 file sets owner permissions to read/write/execute (7) and group/others to read/execute (5), while chmod u+x file adds execute permission for the owner only. This command operates on files and directories alike, though execute on directories controls traversal rather than execution. Default permissions for newly created files and directories are determined by the , a value that masks out specific bits from the system's initial modes. Files start with mode 0666 (read/write for all categories, no execute), and directories with 0777 (read/write/execute for all); the umask subtracts its value bitwise to clear permissions (e.g., a common umask of 0022 yields 0644 for files and 0755 for directories by removing write for group/others on files and write for others on directories). The [umask](/page/Umask) command sets or displays this value in the current , influencing all subsequent creations until changed. This foundational model provides the basis for more advanced permission mechanisms, such as special bits that extend privilege handling.

Special Permission Bits

In operating systems, special permission bits extend the standard read (r), write (w), and execute (x) permissions by enabling specific privilege escalations or restrictions during file access or execution. The setuid bit, formally known as the set-user-ID bit and defined by the S_ISUID flag with an value of 04000, allows an executable file to run with the effective user ID of its owner rather than the invoking user's ID. This mechanism supports tasks requiring elevated privileges without granting them broadly to users. The setuid bit is set using the command in mode as u+s (e.g., chmod u+s file) or in mode by prefixing the standard permissions with 4 (e.g., chmod 4755 file). When active, it modifies execution so the effective user ID aligns with the file owner's ID, facilitating secure delegation of administrative functions. For context, the setgid bit (S_ISGID flag, 02000, g+s) operates analogously but for group privileges: when set on an executable, it sets the effective group ID to that of the file's group, enabling group-specific resource access; on directories, it enforces new files to inherit the directory's group ownership. The sticky bit (S_ISVTX flag, 01000, t or o+t) applies primarily to directories, preventing users from deleting or renaming files unless they own the file or directory, or possess privileges; this is commonly used in shared writable directories like /tmp. These bits appear distinctly in the long listing format of the command. For setuid or setgid, an 's' replaces the execute 'x' in the owner or group permission triplet if execute is also granted (e.g., -rwsr-xr-x for setuid with owner execute, or -rwxr-sr-x for setgid); if execute is absent, a capital 'S' indicates the bit alone (e.g., -rwSr-xr-x). The shows as a 't' in the other's execute position (e.g., drwxrwxrwt), or 'T' if execute is not set.
Permission BitFlagOctal ValueSymbolic NotationEffect on ExecutablesEffect on Directories
S_ISUID04000u+sRuns with file owner's effective N/A
SetgidS_ISGID02000g+sRuns with file group's effective GIDNew files inherit directory's group
StickyS_ISVTX01000o+t or tHistorically restricted paging (obsolete)Restricts file deletion to owners

Mechanics of Setuid

Execution on Files

When an executable with the setuid bit set is invoked in systems, the , via the exec family of functions, creates a new image where the effective user ID (EUID) is set to the user ID of the 's owner, while the real user ID (RUID) remains unchanged and matches that of the invoking . The saved set-user-ID is also updated to the owner's user ID, enabling the to perform actions as if owned by the 's owner during its execution. This mechanism is defined in the standard and applies only if the does not have the ST_NOSUID set. This privilege elevation allows a non-privileged to temporarily acquire the owner's permissions. For instance, a standard executing the /usr/bin/[passwd](/page/Passwd) program, which is owned by and has the setuid bit enabled, gains -level access solely for updating password files, without altering the caller's R. The scope of privileges depends on the file owner: in setuid- scenarios, where the owner is the (UID 0), the process obtains full administrative capabilities; in contrast, setuid-nonroot cases limit the process to the specific, potentially restricted privileges of the non- owner, such as access to particular resources without system-wide control. Upon termination of the process—whether through normal exit or error—the elevated EUID is no longer active, as the process ceases to exist and cannot propagate its privileges to new processes unless explicitly forked beforehand. For security, setuid executables should be invoked using absolute paths (e.g., /usr/bin/passwd) rather than unqualified names resolved via the environment variable, to avoid executing unintended malicious binaries that could exploit the setuid mechanism if placed in searchable directories.

Behavior on Directories

In systems, the setuid bit on directories is implementation-defined and often ignored, meaning it does not alter the behavior of file creation or ownership inheritance in most standard environments. According to the standard, whether requests to set or clear the set-user-ID-on-execution bit (S_ISUID, equivalent to mode 04000) on non-regular files such as directories are honored is left to the discretion of the implementation, allowing systems to disregard such operations without violating compliance. In practice, this results in the bit having no functional effect on directories across many platforms, including , where new files and subdirectories created within a setuid directory inherit the user ID () of the creating process rather than the directory's owner. However, on select systems like certain configurations of , the setuid bit can enforce UID inheritance when explicitly enabled. In , if the S_ISUID bit is set on a directory and the filesystem is mounted with the MNT_SUIDDIR option (typically on UFS filesystems), any new files or subdirectories created inside will adopt the directory's owner , overriding the creating user's ; additionally, the execute bits are cleared on new files for security, and the bit is propagated to new subdirectories. This mechanism is a non-standard extension designed primarily for specialized environments, such as fileservers running FTP or , where maintaining consistent file ownership across multiple users is essential to prevent permission conflicts in shared workspaces— for instance, ensuring uploaded files in a public are owned by a service account rather than individual contributors. The GNU Coreutils documentation notes that such behavior occurs on only a few systems, emphasizing its rarity and advising against reliance in portable scripts, as explicitly permits ignoring these bits on directories. A key limitation of the setuid bit on directories is that it has no impact on execution privileges, as directories are not in the same manner as files; it solely influences assignment during and does not elevated permissions to processes interacting with the directory. It is frequently combined with the setgid bit to achieve fuller control over , allowing new files to match both the directory's and group ID (GID) for collaborative scenarios. To check the setuid bit on a directory, the ls -ld command displays it as an 's' in the owner's execute position (e.g., drwxr-sr-x), while setting it requires chmod u+s <directory> or numeric mode like chmod 4xxx <directory>, though these operations may succeed without effect on unsupported systems. Platform variations further complicate its use: and most POSIX-compliant systems ignore the bit entirely for directories, treating it as a no-op during file creation. In contrast, requires kernel configuration via the SUIDDIR option and is limited to local UFS filesystems, with no support on or other modern filesystems. Networked filesystems like NFS typically do not honor setuid on directories due to security concerns over cross-machine UID mapping, rendering the bit ineffective in distributed environments such as Files or standard NFSv3/v4 exports.

Implementation Details

Process Credentials

In Unix-like operating systems, particularly , process credentials are managed by the through specific and group identifier fields stored in the struct cred , which is immutable once committed to a task except for and keyring modifications. These credentials include the real ID (RUID), which identifies the owning the process and is preserved across fork() and execve() calls; the effective ID (EUID), which determines the process's permissions for accessing resources like files; and the saved set-user-ID (SUID), which stores a previous EUID value for potential restoration during privilege changes. Equivalent group identifiers exist for setgid functionality: the real group ID (RGID) for ownership, the effective group ID (EGID) for permission checks, and the (SGID) for group privilege switching. During non-setuid execution of a via the execve() , the process inherits credentials from its parent, with the RUID unchanged, the EUID unchanged, and the SUID set to the EUID; if the caller has EUID equal to RUID (typical for unprivileged processes), all three will match the caller's real ID. In contrast, when executing a setuid —where the file's set-user-ID bit is set—the adjusts the credentials as follows: the EUID is set to the user ID of the file's owner to grant elevated privileges for the duration of execution, while the RUID remains the caller's ID to preserve the original ownership context; the SUID is then assigned the value of the new EUID (the file owner's ID), allowing to later switch privileges back using calls like setreuid() if needed. The same logic applies to setgid binaries for group credentials: the EGID is set to the file's group ID, the RGID stays as the caller's, and the SGID captures the new EGID for potential reversal. These adjustments occur only if certain conditions are met, such as the absence of the no_new_privs flag, a non-nosuid filesystem mount, and no active tracing via ptrace(). The assignment of these credentials during execve() can be illustrated in pseudocode, reflecting the kernel's handling in the do_execve() path:
if (file_has_setuid_bit) {
    new_euid = file_owner_uid;
    new_suid = new_euid;  // Save the elevated UID
    // RUID unchanged: new_ruid = current_ruid
} else {
    new_euid = current_euid;
    new_suid = new_euid;
    new_ruid = current_ruid;
}
// Commit new credentials to task's cred structure
task->cred->uid = {new_ruid, new_euid, new_suid};
This simplifies the kernel's logic, where the real IDs are inherited unchanged, and special bits trigger the effective and saved ID updates before committing the immutable struct cred. For group IDs, the process mirrors this, substituting GIDs in place of UIDs when the set-group-ID bit is present.

System Calls Involved

The and fchmod system calls are used to set the setuid bit on files and directories. The function changes the mode of a file specified by pathname, while fchmod operates on an open file descriptor; both allow setting the set-user-ID bit (S_ISUID, octal 04000) in the file mode bits, which enables the special permission for subsequent executions. These calls require the calling process to have appropriate privileges, such as the effective user ID matching the file owner or possession of the CAP_FOWNER capability; otherwise, they return -1 with errno set to EPERM. Note that on some filesystems, writing to the file without the CAP_FSETID capability may automatically clear the setuid bit as a security measure. The execve system call and its family (such as execl, execvp) trigger the setuid mechanism during program loading. When executing a file with the setuid bit set, execve changes the effective user ID (EUID) of the new process to the file owner's UID, provided certain conditions are met, such as the filesystem not being mounted with the nosuid option (MS_NOSUID flag). The real user ID (RUID) remains unchanged unless the process is privileged, and the original EUID is copied to the saved set-user-ID for potential later use. If the process is being ptraced, the no_new_privs prctl attribute is set, or the filesystem is nosuid, the setuid bit is ignored (no EUID change to file owner), but execve still succeeds in executing the program unless other permission restrictions apply. At runtime, the setuid, seteuid, and setreuid system calls allow processes—particularly those launched with setuid—to modify user ID credentials, but only under specific conditions tied to saved set-user-ID privileges. The setuid call sets the effective UID and, if the process has the CAP_SETUID capability, also updates the real UID and saved set-user-ID; for non-privileged processes, it succeeds only if the specified UID matches the real or saved set-user-ID. Similarly, seteuid permits temporary changes to the effective UID, enabling setuid-root programs to drop and regain privileges via the saved set-user-ID, while setreuid simultaneously sets both real and effective UIDs for more flexible management. These calls return -1 with errno set to EPERM if the process lacks CAP_SETUID and the UID does not match the real or saved set-user-ID, preventing unauthorized privilege escalations. For verification purposes, the getuid and geteuid system calls retrieve the current user IDs without error conditions. getuid returns the real user ID of the calling process, while geteuid returns the effective user ID, allowing programs to inspect changes induced by setuid execution. These queries always succeed and do not set errno, providing a reliable way to confirm the active privileges in process s.

Practical Usage

Permission Verification

Permission verification for the setuid bit on files and directories in systems can be performed using both command-line tools and programmatic interfaces, allowing administrators and developers to inspect whether the special permission is enabled. The ls -l command provides a straightforward way to visually inspect setuid permissions in the long listing format, where the owner execute permission position (the third character in the permission string) displays a lowercase 's' if the setuid bit is set and the execute bit is also enabled, or an uppercase 'S' if the setuid bit is set but the execute bit is not. For example, output like -rwsr-xr-x indicates setuid with owner execute privileges, while -rwSr-xr-x shows setuid without the execute bit. This notation applies similarly to directories, though setuid on directories typically has limited beyond in some filesystems. The distinction between 's' and 'S' helps identify not only the presence of the setuid bit but also the accompanying execute permission status. For more detailed numerical inspection, the stat command outputs the file mode in octal, where the setuid bit corresponds to the 4 in the leading digit (e.g., 4755 for a setuid executable with standard read/write/execute permissions). Running stat filename reveals the full mode bits, such as Access: (04755/-rwsr-xr-x), confirming the setuid presence through the 4xxx pattern. This tool is particularly useful for scripting or precise verification, as it provides raw mode values without symbolic interpretation. To locate all setuid-enabled files system-wide, a common one-liner uses the find command: find / -perm -4000, which searches for files where the setuid bit is set (the -4000 specifies the bit in , with the minus indicating it must be present regardless of other permissions). This can be extended with -type f to limit to files or -exec ls -l {} \; to display details, aiding in audits by listing potential privilege-escalation vectors. For directories, the same command identifies them if the bit is set, though such cases are rare and often ignored in practice. Programmatically, applications in C or similar languages can verify the setuid bit using the stat() or fstat() to retrieve the file's st_mode field, then checking if (st_mode & S_ISUID) != 0, where S_ISUID is the macro defined as 04000 in (S_IXUSR << 3). The access() function can also test execute permissions but does not directly reveal the setuid bit; thus, stat() is preferred for comprehensive checks. This approach, defined in POSIX standards, ensures portable detection across Unix-like systems.

Common Setuid Programs

One prominent example of a setuid-root program is the passwd command, which permits non-root users to modify their own password entries in the protected /etc/shadow file—a operation that necessitates root privileges for file access and integrity. By executing with the effective user ID set to root, passwd ensures that only the invoking user's record is altered, leveraging for secure authentication and validation. The ping utility provides another standard case, traditionally implemented as setuid-root to enable the creation of raw IP sockets for sending ICMP echo requests and receiving responses, a low-level network operation restricted to privileged processes to mitigate potential denial-of-service risks. This allows diagnostic tools like ping to be accessible system-wide without requiring users to switch to root. Many contemporary Linux distributions supplement or replace this with the CAP_NET_RAW capability for finer-grained privilege control, but the setuid approach remains in legacy or minimal configurations. Sudo, the sudo command, operates as a setuid-root binary to facilitate controlled privilege escalation, allowing authorized users to execute specified commands with root (or other user) privileges based on policies defined in /etc/sudoers. This mechanism supports administrative delegation while enforcing logging and authentication, avoiding the need for direct root logins. In certain Linux distributions, the mount command is set as setuid-root to permit non-root users to attach filesystems designated with the user option in /etc/fstab, such as floppies or USB drives, thereby promoting usability for removable media without full administrative access. The user mount option explicitly relies on this setuid configuration in the mount binary to override the kernel's default nouser restriction. To demonstrate setuid behavior in code, the following simple C program prints the real and effective user IDs upon execution:
c
#include <stdio.h>
#include <unistd.h>

int main(void) {
    [printf](/page/Printf)("Real UID: %d\n", getuid());
    [printf](/page/Printf)("Effective UID: %d\n", geteuid());
    return 0;
}
When compiled into an executable owned by with the setuid bit enabled (via chmod u+s), running it as a non-privileged will display the caller's real UID alongside an effective UID of 0 (), illustrating the inheritance of the file owner's credentials for the process.

Security Considerations

Potential Risks

The setuid mechanism enables programs to execute with the privileges of their owner, often , which introduces significant risks of if vulnerabilities are present in those programs. Attackers can exploit bugs, such as buffer overflows or input validation errors, to overwrite memory and redirect execution to malicious code, thereby gaining elevated privileges like access. This occurs because the effective user ID (EUID) of the process temporarily matches the file owner's ID during execution, allowing untrusted code to perform actions beyond the caller's permissions. Historical exploits frequently targeted setuid-root binaries through s, enabling local users to escalate privileges. For instance, in AIX 4.2 and earlier, the utility contained a vulnerability that allowed local attackers to gain privileges by providing a long command-line argument, as the program processed input without adequate bounds checking while running with setuid-root permissions. Similarly, vulnerabilities in and umount utilities in various systems, such as s from long relative paths, permitted local by exploiting the elevated context needed for filesystem operations. These incidents highlight how seemingly innocuous utilities, when setuid, become prime targets for memory corruption attacks that lead to full system compromise. More recent examples include CVE-2025-23395 in the Screen 5.0.0 utility (as of May 2025), where setuid-root execution in the logfile_reopen() function fails to drop privileges while operating on user-controlled files, enabling local attackers to gain root access. Race conditions, particularly time-of-check-to-time-of-use (TOCTOU) issues, pose another threat when setuid programs interact with files. In such scenarios, a program checks a file's permissions or attributes at one point but uses them later after a potential change, allowing attackers to manipulate the file between the check and use phases. For example, in the Linux kernel's execve() implementation, a TOCTOU vulnerability enabled unauthorized execution of setuid files by altering permissions (e.g., adding setuid bits) between the initial open and the privilege application, potentially leading to unintended root access during package updates or file operations. This type of flaw exploits the non-atomic nature of filesystem interactions in privileged contexts. Overuse of the setuid bit expands the unnecessarily, as each setuid program represents a potential for if not rigorously audited. When developers or administrators setuid more binaries than required—violating the principle of least privilege—they increase the number of components running with elevated rights, amplifying the impact of any single vulnerability. Studies of setuid-to-root binaries have identified dozens of flaws stemming from this practice, underscoring how broader deployment heightens systemic risks without corresponding benefits. In modern containerized environments like , setuid binaries can bypass isolation mechanisms, enabling from within a to the system. Containers often inherit capabilities, and a vulnerable setuid inside one can execute with -level privileges if not restricted, such as through user namespaces or drops. This threat is exacerbated in multi-tenant setups, where compromised containers might leverage setuid to escape boundaries and affect the broader infrastructure.

Mitigation Strategies

To mitigate the security risks associated with setuid programs, administrators should adhere to the principle of least privilege by avoiding setuid- binaries whenever possible and instead granting only the specific required for functionality. capabilities divide privileges into fine-grained units, allowing programs to perform necessary operations without full access. For instance, the utility traditionally required setuid- to create sockets for ICMP echo requests, but modern distributions configure it with the CAP_NET_RAW using the setcap command (e.g., setcap cap_net_raw+ep /bin/[ping](/page/Ping)), limiting its scope to raw access and reducing the if exploited. Auditing setuid executions is essential for detecting unauthorized or anomalous usage. The auditd daemon, part of the Audit Framework, can monitor executions by adding rules via auditctl to track the execve where the saved user ID differs from the real user ID (e.g., auditctl -a always,exit -F arch=b64 -S execve -F suid!=0). This generates logs for setuid transitions, enabling forensic analysis of privilege escalations. Where setuid is unavoidable, alternatives such as wrappers, service managers, or mandatory access controls provide safer mechanisms for privilege management. Setuid wrappers are small privileged binaries that invoke unprivileged scripts or programs after validating inputs, preventing direct exposure of elevated privileges to interpreters like shells. Systemd services offer a structured alternative by running processes under specific users or with dynamic users (via DynamicUser=yes in unit files), avoiding setuid bits altogether while integrating with privilege separation. Additionally, confinement tools like AppArmor and SELinux enforce mandatory access controls on setuid programs, restricting their file access, network capabilities, and system calls even after privilege escalation. For example, AppArmor profiles can limit a setuid binary to read-only access on specific paths, while SELinux policies define type enforcement to prevent unauthorized transitions. Regular audits and maintenance guidelines help minimize unnecessary setuid exposure. Administrators can identify setuid and setgid binaries using the find command (e.g., find / -xdev $ -perm -4000 -o -perm -2000 $ to search across the root filesystem), reviewing results to disable bits on non-essential files with chmod u-s or chmod g-s. Package managers like dpkg or rpm can confirm if binaries belong to installed software, aiding decisions to remove or replace them. To further restrict setuid execution, non-root filesystems should be mounted with the nosuid option, which prevents the from honoring set-user-ID, set-group-ID bits, or file capabilities on executables within that . This is particularly useful for user-writable partitions like /home or /tmp, as specified in /etc/fstab (e.g., UUID=xxx /home [ext4](/page/Ext4) defaults,nosuid,nodev,noexec 0 2), blocking potential privilege escalations from untrusted storage.

Historical Context

Early Development

The setuid mechanism originated at Bell Laboratories in the early 1970s, where it was developed as part of the foundational work on the Unix operating system to provide controlled for multi-user environments. One early motivation was to allow multiplayer games to update shared high-score files securely, without granting full access to users. Invented by , a key member of the Unix team alongside , the feature addressed the need for secure sharing of administrative capabilities without exposing full access. The primary motivation for setuid was to enable ordinary users to run specific programs with elevated permissions belonging to the file's owner, thereby allowing tasks like updating system files while minimizing security risks associated with unrestricted root privileges. This design facilitated privilege sharing in a controlled manner, such as permitting non-root users to modify password entries without granting broader system control. Bell Laboratories filed a patent application for the setuid bit in 1973, which was granted on January 16, 1979, as U.S. Patent 4,135,240, titled "Protection of Data File Contents." The initial implementation appeared in early Research Unix releases, with its first notable application in commands like passwd, which required temporary root privileges to update protected files such as /etc/passwd. Early documentation of the associated setuid is found in the Programmer's Manual, released by in 1979, where it is described under section 2 as a means to change the effective user ID of a . This manual entry marked a key point of formalization, reflecting the mechanism's integration into the core Unix kernel by that time.

Standardization and Evolution

The setuid mechanism achieved formal standardization through POSIX.1-1988 (IEEE Std 1003.1-1988), which defined the setuid bit on executable files and the corresponding s, including setuid() for changing credentials. This standard introduced support for saved set-user-ID via the _POSIX_SAVED_IDS feature, enabling processes to temporarily drop and regain privileges after execution, thereby improving portability across systems. Subsequent revisions, such as POSIX.1-1990 and later, refined these semantics to mandate saved ID handling for enhanced security in privileged applications. Differences emerged between major Unix variants during this period, with System V introducing saved user IDs in the 1980s to allow flexible privilege switching via calls like seteuid(), which could set the effective to the real or saved . In contrast, BSD variants like 4.2BSD relied on setreuid() for swapping real and effective UIDs without native saved ID support, providing similar flexibility but with different semantics that risked permanent privilege loss. By 4.4BSD in 1993, BSD aligned more closely with and System V by adopting the saved model, modifying setuid() to update all UIDs uniformly and reducing historical incompatibilities. In , evolution in the 1990s introduced capabilities as a granular alternative to setuid binaries, debuting in 2.2 (1999) to subdivide privileges into discrete units like CAP_SETUID, mitigating the all-or-nothing risks of full escalation. The library facilitated user-space management of these capabilities, allowing file-based bounding of privileges (e.g., granting only raw to tools like without setuid). This shift aimed to replace many setuid- programs with capability-aware ones, though adoption varied across distributions due to compatibility concerns. Post-2000s developments in Apple ecosystems tightened setuid usage in favor of sandboxing for . macOS, building on its Unix heritage, retained setuid support but imposed restrictions, such as code-signing requirements and discouragement for third-party apps, with sandboxing becoming the preferred mechanism starting in Mac OS X 10.7 Lion (2011) and mandatory for submissions by March 2012. In , introduced in 2007, setuid binaries are unsupported entirely; all applications execute within strict per-app sandboxes that isolate file access and , eliminating the need for UID-based . Recent updates post-2010 in distributions emphasize reducing setuid reliance through capabilities and integration with (LSMs). For instance, SELinux policies enforce type transitions and confinement for setuid processes, preventing unauthorized escalations by labeling executables and auditing privilege changes, as seen in implementations. Some distributions, like , issue best-practice warnings in security audits against broad setuid usage, promoting capability bounding sets and LSM hooks to confine legacy setuid programs without full deprecation. As of 2025, vulnerabilities in setuid binaries continue to be exploited, such as in Screen and (CVE-2025-32463), prompting renewed efforts in distributions to minimize their use in favor of capabilities and other mechanisms.

References

  1. [1]
    chmod
    ### Summary of Special Permissions (setuid, setgid)
  2. [2]
    Linux permissions: SUID, SGID, and sticky bit - Red Hat
    Oct 15, 2020 · SUID executes as the file owner, SGID as the group owner, and the sticky bit restricts file deletion in a directory to only the owner or root.
  3. [3]
    chmod(1) - Linux manual page
    ### Summary of Special Permissions (Setuid, Setgid, Sticky Bit)
  4. [4]
    Special File Permissions (setuid, setgid and Sticky Bit)
    When setuid permission is set on an executable file, a process that runs this file is granted access on the basis of the owner of the file. The access is not ...
  5. [5]
    umask(1p) - Linux manual page
    ### Summary of umask from https://man7.org/linux/man-pages/man1/umask.1p.html
  6. [6]
    <sys/stat.h>
    S_ISUID: set-user-ID on execution; S_ISGID: set-group-ID on execution; S_ISVTX: on directories, restricted deletion flag. The bits defined by S_IRUSR, S_IWUSR ...
  7. [7]
    Permission Bits (The GNU C Library)
    This is equivalent to ' (S_IROTH | S_IWOTH | S_IXOTH) '. S_ISUID ¶. This is the set-user-ID on execute bit, usually 04000. See How an Application Can Change ...
  8. [8]
    exec
    ### Summary of Setuid and Setgid Effects on User and Group IDs with exec Functions
  9. [9]
    Command Injection - OWASP Foundation
    However, since the program does not specify an absolute path ... And since the program has been installed setuid root, the attacker's version of make now runs ...
  10. [10]
    chmod(2) - Linux manual page
    ### Summary on Setuid Bit on Directories
  11. [11]
    chmod(2)
    ### Summary of Setuid on Directories and Effects on New Files/Subdirectories from FreeBSD chmod(2)
  12. [12]
    27.5 Directories and the Set-User-ID and Set-Group-ID Bits - GNU
    On a few systems, a directory's set-user-ID bit has a similar effect on the ownership of new subfiles and the set-user-ID bits of new subdirectories. These ...
  13. [13]
    Understand NFS file permissions in Azure NetApp Files
    Feb 13, 2025 · Setuid has no effect on directories. Setgid. The setgid bit can be used on both files and directories. With directories, setgid can be used ...Nfs Mode Bits · Sticky Bits, Setuid, And... · Setgid
  14. [14]
    Credentials in Linux - The Linux Kernel documentation
    The Linux kernel supports the following types of credentials: Traditional UNIX credentials. The UID and GID are carried by most, if not all, Linux objects.
  15. [15]
    credentials(7) - Linux manual page
    ### Summary of User and Group Identifiers from credentials(7)
  16. [16]
    execve(2) - Linux manual page - man7.org
    The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change ...
  17. [17]
    [PDF] Setuid Demystified - USENIX
    setuid() Although setuid is the only uid-setting sys- tem call standardized in POSIX 1003.1-1988, it is also the most confusing one. First, the required ...
  18. [18]
    setuid(2) - Linux manual page - man7.org
    setuid() sets the effective user ID of the calling process. If the calling process is privileged (more precisely: if the process has the CAP_SETUID capability ...
  19. [19]
    getuid(2) - Linux manual page
    ### Summary of getuid and geteuid
  20. [20]
    permissions - What's the difference between "s" and "S" in ls -la?
    Jan 5, 2012 · The letter s denotes that the setuid (or setgid, depending on the column) bit is set. When an executable is setuid, it runs as the user who owns the executable ...How to search for all SUID/SGID files? - Unix & Linux Stack ExchangeWhat do the fields in ls -al output mean?More results from unix.stackexchange.com
  21. [21]
    stat(1) - Linux manual page - man7.org
    Display file or file system status. Mandatory arguments to long options are mandatory for short options too.Missing: setuid | Show results with:setuid
  22. [22]
    How to get octal file permissions on Linux/Unix command line
    Sep 10, 2023 · You need to use the stat command to view or get octal file permissions for given filename. By default the ls command will not display the permissions on a file ...<|control11|><|separator|>
  23. [23]
    How to Find Files With SUID and SGID Permissions in Linux - Tecmint
    Jul 13, 2023 · SUID is a special file permission for executable files which enables other users to run the file with effective permissions of the file owner.
  24. [24]
    Setuid Programs (GNU Guix Reference Manual)
    A list of <setuid-program> denoting common programs that are setuid-root. The list includes commands such as passwd, ping, su, and sudo.
  25. [25]
    passwd(1) - Linux manual page
    ### Summary of Setuid and Privileges for the passwd Command
  26. [26]
    capabilities(7) - Linux manual page - man7.org
    CAP_SETUID • Make arbitrary manipulations of process UIDs (setuid(2), setreuid(2), setresuid(2), setfsuid(2)); • forge UID when passing socket credentials via ...<|control11|><|separator|>
  27. [27]
    fstab(5) - Linux manual page
    ### Summary on User Mount Option and Relation to Setuid Mount Command
  28. [28]
    Abuse Elevation Control Mechanism: Setuid and Setgid
    Jan 30, 2020 · An adversary may abuse configurations where an application has the setuid or setgid bits set in order to get code running in a different (and possibly more ...
  29. [29]
    CVE-1999-1208 Detail - NVD
    Description. Buffer overflow in ping in AIX 4.2 and earlier allows local users to gain root privileges via a long command line argument.
  30. [30]
    [PDF] Practical Techniques to Obviate Setuid-to-Root Binaries
    Apr 13, 2014 · Trusted, setuid-to-root binaries have been a substantial, long-lived source of privilege escalation vulnerabilities on. Unix systems. Prior work ...
  31. [31]
    CVE-2024-43882 Detail - NVD
    Aug 20, 2024 · In the Linux kernel, the following vulnerability has been resolved: exec: Fix ToCToU between perm check and set-uid/gid usage.<|control11|><|separator|>
  32. [32]
    Docker Security - OWASP Cheat Sheet Series
    The aim of this cheat sheet is to provide a straightforward list of common security errors and best practices to assist in securing your Docker containers.
  33. [33]
    ping(8) - Linux manual page
    ### Summary: ping and Setuid/Capabilities (CAP_NET_RAW)
  34. [34]
    auditctl(8) - Linux manual page
    ### Summary: Monitoring Setuid Executions or Process Executions with auditd
  35. [35]
    Linux Script SUID Wrapper - Information Security Stack Exchange
    Oct 8, 2017 · Given that it provides a gateway to privileged access, using setuid programs should be considered a last resort for providing functionality.How to approach creating a Linux app that requires root privilege?Why is SUID disabled for shell scripts but not for binaries?More results from security.stackexchange.com
  36. [36]
    Finding setuid binaries on Linux and BSD
    Use `find` with `-perm -4000` to find setuid binaries, excluding other devices with `-xdev` and root-owned files with `-user root`.Finding files with setuid bit · Exact match · What to do with the results?
  37. [37]
    mount(8) - Linux manual page - man7.org
    The mount command automatically canonicalizes all paths (from the command line or fstab). This option can be used in conjunction with the -f flag for paths that ...
  38. [38]
    US4135240A - Protection of data file contents - Google Patents
    This invention relates to computer systems, and more particularly, to computer systems having multiple users and multiple data files.
  39. [39]
    setuid
    If the process has appropriate privileges, setuid() shall set the real user ID, effective user ID, and the saved set-user-ID of the calling process to uid.
  40. [40]
    None
    ### Summary of BSD vs System V Setuid Differences, Especially Saved IDs and Evolution
  41. [41]
    [PDF] Linux Capabilities: making them work
    Jul 23, 2008 · In a traditional UNIX system this would not be possible, as executing a setuid-root program would always raise its privilege. To completely ...
  42. [42]
  43. [43]
    Security of runtime process in iOS, iPadOS, and visionOS
    Dec 19, 2024 · Sandboxing is designed to prevent apps from gathering or modifying information stored by other apps. Each app has a unique home directory for ...Missing: post- 2000s
  44. [44]
    Using SELinux | Red Hat Enterprise Linux | 8
    For example, mapping a Linux user to the SELinux user_u user, results in a Linux user that is not able to run unless configured otherwise set user ID (setuid) ...Missing: integration | Show results with:integration