You see a file with permissions 4755 or a directory with permissions 1777. Those extra digits are special permissions. They’re powerful and dangerous if you don’t understand them.
Let’s demystify sticky bit, setuid, and setgid.
The Permission Basics (Quick Review)
Normal permissions are three digits: rwx for owner, group, and others.
-rw-r--r-- 1 alice users 1024 Apr 16 10:00 file.txtRead the permissions as:
-— Type (file)rw-— Owner (alice) can read and writer--— Group (users) can readr--— Others can read
Special permissions are a fourth digit prepended to these three.
Setuid (Set User ID)
What it does: When you execute a setuid binary, it runs as the owner, not you.
Symbol: s in the owner execute position (or S if owner can’t execute)
Example: The sudo binary
$ ls -l /usr/bin/sudo-rwsr-xr-x 1 root root 236K Apr 16 10:00 /usr/bin/sudoThe s in position 1 means “setuid”. When you run sudo, it runs as root, even though you executed it.
How to set it:
chmod u+s /path/to/binary# Or numericallychmod 4755 /path/to/binaryThe first digit is 4 for setuid.
Why it’s dangerous:
If you setuid a binary with a vulnerability, anyone can exploit it to become the owner. That’s why /bin/passwd (which changes your password) is setuid root — you need root privileges to modify /etc/shadow, but regular users need to be able to run it.
Real-world examples:
ls -l /usr/bin/passwd /usr/bin/sudo /usr/bin/fusermount# All have setuid bit setThese tools need elevated privileges but regular users need to run them.
Security rule: Never setuid a script (#! shell or Python). Only setuid compiled binaries, and only if you’ve audited the code.
Setgid (Set Group ID)
What it does: When you execute a setgid binary, it runs as the group owner, not your group. On directories, newly created files inherit the directory’s group.
Symbol: s in the group execute position (or S if group can’t execute)
Example: A shared project directory
$ mkdir /project$ chown :project /project$ chmod g+s /project$ ls -ld /projectdrwxr-sr-x 2 alice project 4096 Apr 16 10:00 /projectThe s in the group execute position means “setgid”. Now any file created in /project automatically belongs to the project group, regardless of who creates it.
How to set it on a directory:
chmod g+s /path/to/directory# Or numericallychmod 2755 /path/to/directoryThe first digit is 2 for setgid.
Real-world use case: Shared team directories
mkdir -p /shared/docschown alice:team /shared/docschmod 2775 /shared/docs
# Now anyone in the 'team' group can create files here,# and those files automatically belong to 'team'Check it:
$ touch /shared/docs/test.txt$ ls -l /shared/docs/test.txt-rw-r--r-- 1 alice team 0 Apr 16 10:00 test.txt# File is owned by alice:team, even though alice created itOn binaries: Setgid binaries are rare and work similarly to setuid — the binary runs with the group’s permissions.
Sticky Bit
What it does: On directories, it restricts deletion. You can only delete files you own, even if you have write permission to the directory.
Symbol: t in the others execute position (or T if others can’t execute)
Example: /tmp
$ ls -ld /tmpdrwxrwxrwt 10 root root 4096 Apr 16 16:15 /tmpThe t at the end means sticky bit. Anyone can create files in /tmp, but you can only delete your own.
Without sticky bit, anyone could delete anyone else’s files:
rm /tmp/someone_elses_file.txt # This would work without sticky bitWith sticky bit, you get “Operation not permitted”.
How to set it:
chmod o+t /path/to/directory# Or numericallychmod 1777 /path/to/directoryThe first digit is 1 for sticky bit.
Real-world use case: Shared upload directories
mkdir /uploadschmod 1777 /uploads
# Everyone can write files, but only the owner can delete themPrevents users from deleting each other’s uploads.
Reading Special Permissions
When you see permissions, decode them from left to right:
-rwsr-xr-x^ ^| +-- setuid (runs as owner)+------ regular file (not special file type)Or with all three special bits:
-rwsr-sr-t ^ ^ ^ | | +-- sticky bit (only owner can delete) | +---- setgid (inherited group) +------- setuid (runs as owner)Numerically:
4755^+-- setuid bit (4)2755^+-- setgid bit (2)1777^+-- sticky bit (1)You can combine them:
7755 = setuid (4) + setgid (2) + sticky bit (1) + 755 permissionsViewing Special Bits in Detail
Use stat:
stat /usr/bin/sudo# Shows: Access: (4755/-rwsr-xr-x) Uid: (0/root) Gid: (0/root)
stat /tmp# Shows: Access: (1777/drwxrwxrwt)Or use find:
# Find all setuid binaries on the systemfind / -perm -4000 -type f 2>/dev/null
# Find all setgid binariesfind / -perm -2000 -type f 2>/dev/null
# Find directories with sticky bitfind / -perm -1000 -type d 2>/dev/nullSecurity Audit
Audit setuid binaries on your system:
find / -perm -4000 -type f -exec ls -l {} \; 2>/dev/null
# Sample output:# -rwsr-xr-x 1 root root /usr/bin/sudo# -rwsr-xr-x 1 root root /usr/bin/passwd# -rwsr-xr-x 1 root root /usr/bin/chfnEach of these is a potential security entry point. Any vulnerability here is a privilege escalation.
Common Real-World Examples
setuid:
ls -l /usr/bin/sudo /usr/bin/passwd /usr/bin/chsh /usr/bin/fusermount# All setuid for security/functionality reasonssetgid on directories:
mkdir /projectchown alice:project /projectchmod 2770 /project # rwxrwx--- with setgid
# All files created in /project belong to 'project' groupsticky bit:
ls -ld /tmp /var/tmp# Both have sticky bit to prevent accidental deletionThe Security Rule of Thumb
- setuid: Only on system binaries after careful review. Never on scripts.
- setgid: Safe on directories for shared ownership. Use on directories with shared group access.
- sticky bit: Safe on world-writable directories to prevent accidental deletion.
You’ll rarely need to set these yourself. But when you do, understand the implications. A wrong setuid bit is a privilege escalation waiting to happen.
Your system already has examples on binaries like sudo and passwd. That’s by design — they need elevated privileges to work. But any setuid binary you create is a security risk unless thoroughly audited.