LFCS 37 ๐ง Special Permissions โ setuid, setgid, sticky
The nine permission bits describe who can read, write, and execute a file. Three additional bits describe how the execution behaves and how the directory handles deletion. The setuid bit makes a program run as the file’s owner. The setgid bit makes a program run as the file’s group, or makes a directory pass its group to new files. The sticky bit restricts deletion in a shared directory. These three bits are the source of both the standard Unix behaviors โ passwd, sudo, /tmp โ and some of the most dangerous misconfigurations in the system.
Key point: The setuid and setgid bits change the identity of the running process. A setuid-root program runs as root, regardless of who started it. This is why the bits are audited carefully and why most distributions ignore them on scripts.
Why special permissions exist
The password problem. The /etc/shadow file stores the password hashes, and it is readable only by root. A regular user who runs passwd must write to it. The passwd binary is owned by root and has the setuid bit set, so it runs as root and writes to the shadow file. Without the setuid bit, the user could not change their own password.
The shared-directory problem. A team directory must be writable by every member, and every file created in it must belong to the team’s group. The setgid bit on the directory makes new files inherit the directory’s group, so the members can read and write each other’s files.
The temporary-directory problem. The /tmp directory is writable by everyone, and every process creates its temporary files there. Without the sticky bit, any user could delete any file in /tmp. The sticky bit restricts deletion to the file’s owner.
The delegation problem. A program that needs a specific capability, such as ping (raw sockets) or mount (mounting filesystems), can be given the setuid bit instead of being run as root by the user. The bit delegates the specific privilege without giving the full root shell.
The audit problem. A setuid-root binary is a potential privilege escalation. An attacker who finds a buffer overflow in a setuid program gains root. The setuid bits on the system are audited, and the ones that are not necessary are removed.
The script problem. The setuid bit is ignored on shell scripts by the Linux kernel. A script with the setuid bit does not run as the owner; it runs as the user who started it. The kernel’s behavior prevents the trivial escalation that would otherwise be possible with a script that the user can edit.
The LD_PRELOAD problem. A setuid program runs in a controlled environment. The loader ignores LD_PRELOAD and similar variables for setuid programs, so the user cannot inject a library into the privileged process. The protection is part of the design.
a. The setuid bit
The setuid bit is set with the octal 4 prefix or the symbolic u+s. The bit is represented in ls -l by an s in the user execute position, and an S when the execute bit is not set.
The octal and symbolic forms
chmod 4755 /usr/local/bin/program
chmod u+s /usr/local/bin/program
Both forms set the setuid bit. The 4755 sets the bit and the standard 755 permissions.
The ls -l representation
ls -l /usr/local/bin/program
# -rwsr-xr-x 1 root root ... program
The s in the fourth character is the setuid bit. The execute bit is set, so the s is lowercase.
The missing execute bit
chmod 4644 /usr/local/bin/program
ls -l /usr/local/bin/program
# -rwSr--r-- 1 root root ... program
The S is uppercase, which means the setuid bit is set but the execute bit is not. The setuid bit has no effect without the execute bit.
The effect
A setuid program runs with the effective UID of the file’s owner, not the UID of the user who started it.
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
The passwd binary is owned by root and has the setuid bit. A regular user who runs it becomes root for the duration of the program, which is why the program can write to /etc/shadow.
The real and effective UID
The kernel tracks both the real UID (the user who started the process) and the effective UID (the identity used for permission checks). A setuid program has a real UID of the user and an effective UID of the file’s owner.
Real UID: the user who ran the program
Effective UID: the owner of the setuid file
The program can call setuid to switch between them, which is how it drops privileges when the privileged operation is complete.
The listing
find / -perm -4000 -type f 2>/dev/null
The command lists every setuid file on the system. The -perm -4000 matches the setuid bit. The output is the list of programs that can elevate to their owner’s privileges.
The common setuid programs
| Program | Owner | Purpose |
|---|---|---|
passwd | root | Write to /etc/shadow |
sudo | root | Run commands as another user |
su | root | Switch user |
mount | root | Mount filesystems |
ping | root | Raw sockets |
chsh | root | Change the login shell |
newgrp | root | Change the primary group |
The list varies by distribution. Some distributions move ping to a capability-based approach instead of setuid.
The risks
A setuid-root program is a privilege escalation target. A buffer overflow, a path traversal, or a logic bug in the program lets an attacker run arbitrary code as root. The setuid programs on a system should be audited, and any that are not necessary should have the bit removed.
The script exception
The Linux kernel ignores the setuid bit on scripts.
chmod 4755 script.sh
./script.sh
# The script runs as the current user, not the owner.
The behavior is deliberate. A script is interpreted by bash, python, or another interpreter, and the interpreter does not run as root. The kernel would have to elevate the interpreter, which would be trivially exploitable.
The workaround
If a script must run as root, the standard approach is a compiled wrapper with the setuid bit that calls the script, or a sudo rule that allows the specific command, or a systemd service that runs the script as root.
b. The setgid bit
The setgid bit is set with the octal 2 prefix or the symbolic g+s. The bit has two meanings: on a file, the program runs as the file’s group; on a directory, new files inherit the directory’s group.
The octal and symbolic forms
chmod 2755 /usr/local/bin/program
chmod g+s /usr/local/bin/program
chmod 2775 /srv/project
chmod g+s /srv/project
The two forms set the bit. The effect depends on whether the target is a file or a directory.
The ls -l representation
ls -l /usr/local/bin/program
# -rwxr-sr-x 1 root developers ... program
ls -ld /srv/project
# drwxrwsr-x 1 root developers ... /srv/project
The s in the seventh character is the setgid bit. The execute bit is set, so the s is lowercase.
The file effect
On a file, the setgid bit makes the program run with the effective GID of the file’s group.
ls -l /usr/bin/wall
# -rwxr-sr-x 1 root tty ... /usr/bin/wall
The wall program is owned by root and belongs to the tty group. It runs with the tty group’s permissions, which lets it write to every terminal.
The directory effect
On a directory, the setgid bit makes new files and subdirectories inherit the directory’s group.
sudo mkdir /srv/project
sudo chgrp developers /srv/project
sudo chmod 2775 /srv/project
A user who creates a file in /srv/project produces a file owned by the user and the developers group, regardless of the user’s primary group.
The shared-directory pattern
The setgid directory is the standard pattern for a shared team directory.
sudo groupadd developers
sudo mkdir /srv/project
sudo chgrp developers /srv/project
sudo chmod 2775 /srv/project
The directory is writable by the group, and every file created inside it belongs to the group. Every member can read and write every file.
The inherited setgid
A subdirectory created inside a setgid directory inherits the setgid bit. The inheritance propagates down the tree.
mkdir /srv/project/subdir
ls -ld /srv/project/subdir
# drwxrwsr-x ... /srv/project/subdir
The s is present in the subdirectory, and the group is developers.
The listing
find / -perm -2000 -type f 2>/dev/null
find / -perm -2000 -type d 2>/dev/null
The commands list the setgid files and directories on the system.
The common setgid programs
| Program | Group | Purpose |
|---|---|---|
wall | tty | Write to terminals |
write | tty | Write to a terminal |
ssh-agent | โ | Manage keys |
crontab | crontab | Edit the crontab |
The list is shorter than the setuid list, because the group-based elevation is less common.
The risks
A setgid program is a smaller risk than a setuid-root program, because the group has fewer privileges. A setgid-directory is a risk only if the group has access it should not have.
c. The sticky bit
The sticky bit is set with the octal 1 prefix or the symbolic o+t. On a file, the bit has a historical meaning that is no longer used on modern Linux. On a directory, the bit restricts deletion to the file’s owner.
The octal and symbolic forms
chmod 1777 /tmp
chmod o+t /tmp
The 1777 sets the sticky bit and the world-writable permissions.
The ls -l representation
ls -ld /tmp
# drwxrwxrwt 1 root root ... /tmp
The t in the last character is the sticky bit. The execute bit is set, so the t is lowercase.
The missing execute bit
chmod 1666 /tmp
ls -ld /tmp
# drw-rw-rwT 1 root root ... /tmp
The T is uppercase, which means the sticky bit is set but the execute bit is not. The uppercase is unusual.
The directory effect
On a directory, the sticky bit restricts deletion. Only the owner of the file, the owner of the directory, or root can delete or rename the file.
# /tmp is world-writable with the sticky bit.
ls -ld /tmp
# drwxrwxrwt 1 root root ... /tmp
User A creates a file in /tmp. User B cannot delete it, even though the directory is writable, because the sticky bit restricts deletion to the file’s owner.
The /tmp directory
The /tmp directory is the canonical example. It is world-writable because every process needs to create temporary files, and the sticky bit prevents users from interfering with each other.
The shared temporary directory
A group-shared temporary directory uses the sticky bit and the setgid bit.
sudo mkdir /srv/shared-tmp
sudo chgrp developers /srv/shared-tmp
sudo chmod 3770 /srv/shared-tmp
The 3770 combines the sticky bit (1), the setgid bit (2), and the standard 770 permissions. The group can write, the others have no access, and the sticky bit prevents group members from deleting each other’s files.
The listing
find / -perm -1000 -type d 2>/dev/null
The command lists every sticky directory on the system.
The common sticky directories
| Directory | Permissions | Purpose |
|---|---|---|
/tmp | 1777 | Shared temporary files |
/var/tmp | 1777 | Persistent temporary files |
/dev/shm | 1777 | Shared memory |
/run/lock | 1777 | Lock files |
The list varies by distribution, but the pattern is the same.
The file effect
On a regular file, the sticky bit has a historical meaning on some Unix systems. On Linux, the bit is ignored for files. The modern usage is only on directories.
The risks
The sticky bit is a protection, not a privilege. A misconfigured sticky directory is a directory without the protection, which allows users to delete each other’s files. The bit is not an escalation risk.
Complete Example Session
# ============================================
# PART 1: THE SETUID BIT
# ============================================
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
# The s is the setuid bit.
# ============================================
# PART 2: THE SETUID EFFECT
# ============================================
# The passwd program runs as root.
# A regular user can change their own password.
# ============================================
# PART 3: THE SETUID SCRIPT
# ============================================
cat > script.sh << 'EOF'
#!/bin/bash
id
EOF
chmod 4755 script.sh
./script.sh
# uid=1000(alice) gid=1000(alice) ...
# The script runs as alice, not root.
# ============================================
# PART 4: THE SETUID LISTING
# ============================================
find / -perm -4000 -type f 2>/dev/null
# /usr/bin/passwd
# /usr/bin/sudo
# /usr/bin/su
# /usr/bin/mount
# ...
# ============================================
# PART 5: THE SETGID FILE
# ============================================
ls -l /usr/bin/wall
# -rwxr-sr-x 1 root tty ... /usr/bin/wall
# The program runs with the tty group.
# ============================================
# PART 6: THE SETGID DIRECTORY
# ============================================
sudo mkdir /srv/project
sudo chgrp developers /srv/project
sudo chmod 2775 /srv/project
ls -ld /srv/project
# drwxrwsr-x 1 root developers ... /srv/project
# ============================================
# PART 7: THE INHERITED GROUP
# ============================================
touch /srv/project/file.txt
ls -l /srv/project/file.txt
# -rw-r--r-- 1 alice developers ... /srv/project/file.txt
# The file inherits the developers group.
# ============================================
# PART 8: THE STICKY BIT
# ============================================
ls -ld /tmp
# drwxrwxrwt 1 root root ... /tmp
# The t is the sticky bit.
# ============================================
# PART 9: THE STICKY PROTECTION
# ============================================
# Alice creates a file.
touch /tmp/alice-file
# Bob tries to delete it.
su - bob
rm /tmp/alice-file
# rm: cannot remove '/tmp/alice-file': Operation not permitted
# ============================================
# PART 10: THE COMBINED BITS
# ============================================
sudo mkdir /srv/shared-tmp
sudo chgrp developers /srv/shared-tmp
sudo chmod 3770 /srv/shared-tmp
ls -ld /srv/shared-tmp
# drwxrws--T 1 root developers ... /srv/shared-tmp
# The 3 = sticky (1) + setgid (2).
# The group can write.
# The sticky bit prevents deletion by non-owners.
The ten parts showed the setuid bit, its effect, the script exception, the listing, the setgid file, the setgid directory, the inherited group, the sticky bit, the sticky protection, and the combined bits.
Quick Reference
The Special Bits
| Bit | Octal | Symbolic | Symbol | Meaning |
|---|---|---|---|---|
| setuid | 4 | u+s | s in user execute | Run as the file’s owner |
| setgid | 2 | g+s | s in group execute | Run as the file’s group, or inherit the group |
| sticky | 1 | o+t | t in others execute | Only the owner can delete |
The Octal Forms
| Octal | Bits | String |
|---|---|---|
| 4755 | setuid | rwsr-xr-x |
| 2755 | setgid | rwxr-sr-x |
| 1777 | sticky | rwxrwxrwt |
| 6755 | setuid + setgid | rwsr-sr-x |
| 3770 | sticky + setgid | rwxrws--T |
| 7777 | all three | rwsrwsrwt |
The Listing Commands
| Command | Purpose |
|---|---|
find / -perm -4000 -type f | List setuid files |
find / -perm -2000 -type f | List setgid files |
find / -perm -2000 -type d | List setgid directories |
find / -perm -1000 -type d | List sticky directories |
The Common Programs
| Program | Bit | Purpose |
|---|---|---|
passwd | setuid | Write to /etc/shadow |
sudo | setuid | Run commands as another user |
su | setuid | Switch user |
mount | setuid | Mount filesystems |
ping | setuid | Raw sockets |
wall | setgid | Write to terminals |
crontab | setgid | Edit the crontab |
The Common Directories
| Directory | Permissions | Bits |
|---|---|---|
/tmp | 1777 | sticky |
/var/tmp | 1777 | sticky |
/dev/shm | 1777 | sticky |
/srv/project | 2775 | setgid |
Best Practices
โ Do This:
# Use the setuid bit only when necessary.
chmod 4755 /usr/local/bin/program # โ
# Audit the setuid programs on the system.
find / -perm -4000 -type f 2>/dev/null # โ
# Use the setgid bit on shared directories.
chmod 2775 /srv/project # โ
# Use the sticky bit on world-writable directories.
chmod 1777 /tmp # โ
# Combine the bits for a group-shared temporary directory.
chmod 3770 /srv/shared-tmp # โ
# Verify with ls -l.
ls -ld /tmp # โ
# Remove the setuid bit from programs that do not need it.
chmod u-s /usr/local/bin/program # โ
โ Don’t Do This:
# Don't use the setuid bit on a script.
chmod 4755 script.sh # โ The bit is ignored
# Don't set setuid on a program without auditing it.
chmod 4755 myprogram # โ A bug is a root exploit
# Don't use 777 on a shared directory.
chmod 777 /srv/project # โ Anyone can delete anything
# Don't forget the sticky bit on /tmp.
chmod 777 /tmp # โ Users can delete each other's files
# Don't set the setgid bit on a directory without the group.
chmod g+s /srv/project # โ ๏ธ The group must be correct
# Don't rely on the setuid bit for a script.
# Use a compiled wrapper or sudo. # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| setuid ignored on a script | Kernel does not elevate interpreters | Use a binary or sudo |
| setuid bit no effect | Execute bit not set | chmod u+x |
| Files not inheriting the group | setgid bit not set on the directory | chmod g+s |
| Cannot delete a file | Sticky bit on the directory | Only the owner can delete |
| setuid program not elevating | Wrong owner | The owner must be root |
| setgid directory not inheriting | Subdirectory created before the bit | Recreate or set the bit |
| Sticky bit on a file ignored | Historical behavior | The bit is for directories |
Real-World Examples
1. passwd
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... passwd
2. sudo
ls -l /usr/bin/sudo
# -rwsr-xr-x 1 root root ... sudo
3. The Setuid Listing
find / -perm -4000 -type f 2>/dev/null
4. The Setgid Directory
chmod 2775 /srv/project
5. The Shared Team Directory
chgrp developers /srv/project && chmod 2775 /srv/project
6. The Sticky Bit
chmod 1777 /tmp
7. The Combined Bits
chmod 3770 /srv/shared-tmp
8. wall
ls -l /usr/bin/wall
# -rwxr-sr-x 1 root tty ... wall
9. The Setuid Removal
chmod u-s /usr/local/bin/program
10. The Setgid Listing
find / -perm -2000 -type d 2>/dev/null
Visual
The setuid Bit
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE SETUID BIT โ
โ โ
โ -rwsr-xr-x 1 root root ... /usr/bin/passwd โ
โ โฒ โ
โ โ โ
โ s = setuid bit โ
โ โ
โ EFFECT: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Regular user runs passwd. โ โ
โ โ Real UID: the user โ โ
โ โ Effective UID: root (the file's owner) โ โ
โ โ โ โ
โ โ The program can write to /etc/shadow. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ The setuid bit elevates the program to the file's owner. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The setgid Directory
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE SETGID DIRECTORY โ
โ โ
โ drwxrwsr-x 1 root developers ... /srv/project โ
โ โฒ โ
โ โ โ
โ s = setgid bit โ
โ โ
โ EFFECT: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ alice (primary group: alice) creates a file. โ โ
โ โ โ โ
โ โ Without setgid: โ โ
โ โ -rw-r--r-- alice alice file.txt โ โ
โ โ โ โ
โ โ With setgid: โ โ
โ โ -rw-r--r-- alice developers file.txt โ โ
โ โ โ โ
โ โ The file inherits the directory's group. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Sticky Bit
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE STICKY BIT โ
โ โ
โ drwxrwxrwt 1 root root ... /tmp โ
โ โฒ โ
โ โ โ
โ t = sticky bit โ
โ โ
โ EFFECT: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ alice creates /tmp/alice-file. โ โ
โ โ bob tries to delete it. โ โ
โ โ โ โ
โ โ Without the sticky bit: โ โ
โ โ bob can delete the file. โ โ
โ โ โ โ
โ โ With the sticky bit: โ โ
โ โ rm: Operation not permitted โ โ
โ โ โ โ
โ โ Only the file's owner (or root) can delete it. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Combined Bits
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE COMBINED BITS โ
โ โ
โ chmod 3770 /srv/shared-tmp โ
โ โ
โ 3 = 1 (sticky) + 2 (setgid) โ
โ 770 = rwxrwx--- โ
โ โ
โ drwxrws--T 1 root developers ... /srv/shared-tmp โ
โ โฒ โฒ โ
โ โ โ โ
โ โ T = sticky bit (execute not set) โ
โ s = setgid bit โ
โ โ
โ EFFECT: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ The group can read, write, and enter. โ โ
โ โ New files inherit the group. โ โ
โ โ Only the file's owner can delete. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| setuid | 4, run as the file’s owner |
| setgid | 2, run as the file’s group, or inherit the group |
| sticky | 1, only the owner can delete |
u+s | Set the setuid bit |
g+s | Set the setgid bit |
o+t | Set the sticky bit |
-rwsr-xr-x | setuid with execute |
-rwSr--r-- | setuid without execute |
drwxrwsr-x | setgid directory |
drwxrwxrwt | sticky directory |
Key takeaways:
- The setuid bit makes a program run as the file’s owner. A setuid-root program runs as root, regardless of the user who started it. The
passwdbinary is the classic example: it runs as root so it can write to/etc/shadow. - The setuid bit is ignored on scripts. The Linux kernel does not elevate the interpreter, so a setuid shell script runs as the user who started it. The behavior prevents the trivial escalation that would otherwise be possible.
- The setgid bit on a file makes the program run as the file’s group. The
wallbinary is the classic example: it runs with thettygroup so it can write to every terminal. - The setgid bit on a directory makes new files inherit the directory’s group. The pattern is the standard for a shared team directory. The group is preserved across the tree, and every member can read and write every file.
- The sticky bit restricts deletion in a shared directory. Only the owner of the file, the owner of the directory, or root can delete the file. The
/tmpdirectory uses the sticky bit. - The three bits are combined with the octal prefix. The
4is setuid, the2is setgid, and the1is sticky. The3770combines the sticky and setgid bits with the770permissions. - The setuid programs are a privilege escalation target. A bug in a setuid-root program is a root exploit. The setuid bits on the system should be audited, and any that are not necessary should be removed.
- The setgid and sticky bits are protections, not privileges. The setgid directory is a convenience for a shared team. The sticky bit is a protection for a shared temporary directory. Neither is an escalation risk.
Remember: The three special bits extend the standard permission model. The setuid bit elevates a program to its owner’s identity, the setgid bit elevates it to its group’s identity or makes a directory inherit the group, and the sticky bit restricts deletion to the owner. The bits are set with the octal prefix 4, 2, and 1, and they appear in ls -l as s, s, and t. The setuid bit is the dangerous one, and it is audited carefully. The setgid and sticky bits are the standard tools for shared directories. The result is a system where passwd can change the shadow file, where a team directory shares the group, and where /tmp protects each user’s files.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!