What it means
chmod 4755 is chmod 755 plus the setuid bit. Everyone can run the program, and while it runs it has the privileges of the file's owner, not of the user who started it. If root owns the file, the program runs as root. In ls -l it shows as -rwsr-xr-x: the s in the owner's execute position is the setuid bit.
| Who | Digit | Read | Write | Execute | Symbolic |
|---|---|---|---|---|---|
| Special | 4 | setuid (s) |
|||
| Owner (u) | 7 | yes | yes | yes | rws |
| Group (g) | 5 | yes | no | yes | r-x |
| Others (o) | 5 | yes | no | yes | r-x |
In the leading digit, 4 is setuid, 2 is setgid and 1 is sticky. The symbolic equivalent:
chmod u=rwxs,go=rx ./program
A capital S (rwSr-xr-x) means setuid is set but the owner has no execute permission, which is a mistake.
On a file
Setuid exists so ordinary users can do one specific privileged thing. The classic example is passwd: users change their own password, which means writing to /etc/shadow, a file only root can write.
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
Other common setuid-root programs include sudo, su, mount, umount, newgrp and chsh. The exact list varies by distribution; some tools that used to be setuid, like ping, now use file capabilities instead.
On a directory
On Linux, setuid on a directory is ignored. Some BSD systems can be configured to give it a meaning, but don't rely on it. For directories you want setgid or the sticky bit.
Scripts are ignored
Linux ignores setuid on interpreted scripts (files starting with #!). A shell or Python script at 4755 runs as the calling user, not as its owner. That's deliberate: setuid scripts had race conditions that made them unsafe. If a script needs elevated rights, give specific users permission to run it through sudo:
# /etc/sudoers.d/backup (edit with visudo -f)
deploy ALL=(root) NOPASSWD: /usr/local/sbin/backup.sh
Security notes
Every setuid-root binary is a possible privilege escalation. A bug in it, or a way to make it run another command, can give a local user full root. So:
- Never set 4755 on your own programs unless they were written for it: dropping privileges early, sanitizing the environment, validating every input.
- Audit setuid files regularly and compare against what your distribution ships:
sudo find / -xdev -type f -perm -4000 -ls 2>/dev/null
An unexpected setuid file, especially in /tmp, a home directory or a web root, is a strong sign of compromise.
- Mount untrusted filesystems with
nosuid(uploads, removable media,/tmpon many hardened systems), so setuid bits there are ignored:
# /etc/fstab
/dev/sdb1 /srv/uploads ext4 defaults,nosuid,nodev,noexec 0 2
- Prefer capabilities for narrow needs.
setcap cap_net_bind_service=+ep ./serverlets a program bind ports below 1024 without being root.
Clearing it
chown usually clears setuid when ownership changes, and editing a setuid file as a non-root user clears it too. To remove it on purpose:
chmod u-s ./program # or chmod 0755 ./program
Recursive pitfalls
Never use chmod -R 4755. It makes every file in the tree a setuid program owned by whoever owns it, which on a root-owned tree hands root to anyone who can find a usable binary.
Related modes
- chmod 755: the same mode without setuid.
- chmod 2775: the setgid bit on shared directories.
- chmod 1777: the sticky bit on
/tmp.
Toggle setuid, setgid and sticky in the chmod calculator to see the s, S and t flags.