Home / Learn Linux / Lesson 15
Special permissions: SUID, SGID, sticky bit and umask
The permission bits behind passwd, shared folders and /tmp, plus default permissions for new files.
- Lesson
- 15 of 30
- Time
- About 40 minutes
On this page
- Three extra bits
- SUID: run as the owner
- SGID: shared group
- Sticky bit: only delete your own
- The numbers for special bits
- umask: default permissions for new files
- Attributes: beyond permissions
- Common mistakes
- Practice
- Cheat sheet
Three extra bits
Besides rwx for user, group and others, every file has three more permission bits. You'll rarely set them, but they're behind some everyday puzzles: how a normal user can change their password in a root-only file, how a shared folder keeps everyone's files in one group, and why you can't delete other people's files in /tmp.
| Bit | Shows as | On a program | On a directory |
|---|---|---|---|
| SUID (set user ID) | s in the user's x place | Runs as the file's owner | (no effect on Linux) |
| SGID (set group ID) | s in the group's x place | Runs with the file's group | New files inside get the directory's group |
| Sticky | t in the others' x place | (no effect) | Only a file's owner can delete or rename it |
SUID: run as the owner
Your password hash lives in /etc/shadow, which only root can write (lesson 13). Yet you can change your own password. Look at passwd:
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 142552 Feb 2 2026 /usr/bin/passwdThe s where the owner's x would be is the SUID bit. When anyone runs passwd, it runs with the rights of its owner, root, so it can update /etc/shadow. passwd itself makes sure you only change your own password. SUID programs are written very carefully for exactly that reason: any bug in one is a way to become root.
That makes "which programs are SUID root?" a standard security check. Run it on a new server and look out for anything you didn't expect:
$ find / -perm -4000 -type f 2> /dev/null
/usr/lib/cargo/bin/su
/usr/lib/cargo/bin/sudo
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/bin/chsh
/usr/bin/mount
/usr/bin/passwd
/usr/bin/su
/usr/bin/umount
/usr/bin/sudo.ws
/usr/bin/chfn
/usr/bin/fusermount3
/usr/bin/newgrp
/usr/bin/ntfs-3g
/usr/bin/gpasswd-perm -4000 means "has the SUID bit". Every program on this list is one that ordinary users can use to do something as root.
A capital S means SUID is set but the owner doesn't have x, which is almost always a mistake, because there's nothing to run. And SUID is ignored on scripts. Linux only honours it on compiled programs, because scripts can be tricked too easily.
Try it
- Is
suSUID? What aboutsudo?
Answer
$ ls -l /usr/bin/su -rwsr-xr-x 1 root root 68024 Aug 19 14:23 /usr/bin/su $ ls -lL /usr/bin/sudo -rwsr-xr-x 1 root root 1053944 Aug 27 08:15 /usr/bin/sudo
Both are. -L makes ls follow the link, because on Ubuntu 26.04 /usr/bin/sudo is a link to sudo-rs.
SGID: shared group
On a program, SGID works like SUID but with the group. chage uses it to read /etc/shadow, which belongs to the shadow group:
$ ls -l /usr/bin/chage /etc/shadow
-rw-r----- 1 root shadow 952 Oct 21 11:37 /etc/shadow
-rwxr-sr-x 1 root shadow 142344 Feb 2 2026 /usr/bin/chageOn a directory, SGID does something far more useful: every new file created inside gets the directory's group, instead of the creator's own group. That's the fix for the problem at the end of lesson 14, where Ravi's file in the shared team directory ended up in his private group ravi instead of devs.
$ sudo mkdir /srv/team15 $ sudo chown ubuntu:devs /srv/team15 $ sudo chmod 770 /srv/team15 $ sudo -u ravi touch /srv/team15/before.txt $ sudo chmod g+s /srv/team15 $ sudo -u ravi touch /srv/team15/after.txt $ ls -ld /srv/team15 drwxrws--- 2 ubuntu devs 4096 Oct 21 11:37 /srv/team15 $ ls -l /srv/team15 total 0 -rw-r--r-- 1 ravi devs 0 Oct 21 11:37 after.txt -rw-r--r-- 1 ravi ravi 0 Oct 21 11:37 before.txt
before.txt went to Ravi's private group. after.txt landed in devs, so everyone in the team can work with it. New subdirectories inherit the SGID bit too, so the whole tree stays shared.
Try it
- Find every SGID program on the system.
Answer
$ find / -perm -2000 -type f 2> /dev/null
/usr/sbin/pam_extrausers_chkpwd
/usr/sbin/unix_chkpwd
/usr/bin/plocate
/usr/bin/ssh-agent
/usr/bin/expiry
/usr/bin/chage
/usr/bin/crontabSticky bit: only delete your own
/tmp has to be writable by everyone, but that alone would let anyone delete anyone else's files, since deleting is a w on the directory (lesson 14). The sticky bit fixes that:
$ ls -ld /tmp
drwxrwxrwt 12 root root 380 Oct 21 11:37 /tmpThe t at the end is the sticky bit: in this directory, only a file's owner (or root) can delete or rename it. Watch Ravi try:
$ sudo mkdir /srv/drop $ sudo chmod 777 /srv/drop $ touch /srv/drop/mine.txt $ sudo -u ravi rm -f /srv/drop/mine.txt $ ls /srv/drop $ touch /srv/drop/mine.txt $ sudo chmod +t /srv/drop $ sudo -u ravi rm -f /srv/drop/mine.txt rm: cannot remove '/srv/drop/mine.txt': Operation not permitted $ ls -ld /srv/drop drwxrwxrwt 2 root root 4096 Oct 21 11:37 /srv/drop
Without the sticky bit, Ravi deleted a file that wasn't his. With it, he can't. Any directory where several users drop files should have it.
The numbers for special bits
The special bits get a fourth digit, in front of the usual three: SUID is 4, SGID is 2, sticky is 1.
| Mode | Means |
|---|---|
4755 | SUID program |
2770 | Shared team directory (SGID) |
1777 | A /tmp-style drop box (sticky) |
3770 | SGID and sticky together: a team directory where people can't delete each other's files |
$ sudo chmod 2770 /srv/team15 $ stat -c "%a %A" /srv/team15 2770 drwxrws--- $ sudo chmod 1777 /srv/drop $ stat -c "%a %A" /srv/drop 1777 drwxrwxrwt
ubuntu doesn't need sudo for /srv/team15, which it owns, but it does for /srv/drop, which belongs to root.
Letters work as well: u+s, g+s and +t add them, and - removes them.
One catch with 3770 on Ubuntu: the kernel setting fs.protected_regular = 2 stops people opening someone else's file for writing with > or >> in a sticky directory that the group can write to. That protects shared directories from a well-known attack, but it means team members can't add to each other's files there. Use 3770 when everyone only adds their own files, and 2770 when people need to edit each other's work.
Try it
- Make
/srv/team15both SGID and sticky, using a number, and check it.
Answer
$ sudo chmod 3770 /srv/team15 $ stat -c "%a %A" /srv/team15 3770 drwxrws--T
umask: default permissions for new files
Why do new files come out as rw-rw-r-- and directories as rwxrwxr-x? Programs ask for 666 (files) or 777 (directories), and the umask removes bits from that. umask shows yours:
$ umask 0002 $ umask -S u=rwx,g=rwx,o=rx
On Ubuntu, users who have their own private group get a umask of 002: it removes only "write for others". So 666 becomes 664 and 777 becomes 775. Your group is just you, so sharing with it is safe. Root gets 022, which also removes write from the group:
ubuntu@linux:~$ sudo -i root@linux:~# umask 0022 root@linux:~# exit logout
Change it for the current shell and watch new files change:
$ cd /srv/umask-lab $ touch default.txt $ mkdir default-dir $ umask 077 $ touch private.txt $ mkdir private-dir $ ls -l total 8 drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 21 11:37 default-dir -rw-rw-r-- 1 ubuntu ubuntu 0 Oct 21 11:37 default.txt drwx------ 2 ubuntu ubuntu 4096 Oct 21 11:37 private-dir -rw------- 1 ubuntu ubuntu 0 Oct 21 11:37 private.txt
umask 077 removes everything for group and others, which is a good choice for a user that handles secrets. The change lasts only for that shell. To keep it, put umask 077 in ~/.bashrc.
Note that x is never added to new files, whatever the umask: a file only becomes a program when you chmod +x it on purpose.
Try it
- With a umask of
027, what permissions do new files and new directories get?
Answer
Files: 666 minus 027 is 640, rw-r-----. Directories: 777 minus 027 is 750, rwxr-x---.
$ umask 027 $ touch check.txt $ mkdir check-dir $ ls -ld check.txt check-dir drwxr-x--- 2 ubuntu ubuntu 4096 Oct 21 11:37 check-dir -rw-r----- 1 ubuntu ubuntu 0 Oct 21 11:37 check.txt
Attributes: beyond permissions
Linux filesystems like ext4 support a few extra flags that even root has to respect. lsattr shows them and chattr sets them:
| Attribute | Means |
|---|---|
i (immutable) | Can't be changed, renamed, linked to or deleted, by anyone, even root |
a (append only) | Can only be added to, never rewritten or deleted. Good for logs |
$ echo "do not touch" > locked.txt $ sudo chattr +i locked.txt $ lsattr locked.txt ----i---------e------- locked.txt $ sudo rm locked.txt rm: cannot remove 'locked.txt': Operation not permitted $ echo "more" | sudo tee -a locked.txt locked.txt: Operation not permitted (os error 1) more $ sudo chattr -i locked.txt $ rm locked.txt
Root itself couldn't delete it or add to it until the attribute came off. That's useful to protect a config file from being changed by accident, or by an attacker who isn't expecting it. And it's a puzzle you'll meet one day: if root can't delete a file, check lsattr.
Append-only allows adding but nothing else:
$ echo "line 1" > audit.log $ sudo chattr +a audit.log $ echo "line 2" | sudo tee -a audit.log > /dev/null $ echo "overwrite" | sudo tee audit.log audit.log: Operation not permitted (os error 1) overwrite $ cat audit.log line 1 line 2 $ sudo chattr -a audit.log
Common mistakes
- Setting SUID to "fix" a permission problem. A SUID root program that anyone can run is a way into root. Fix the permissions or use
sudorules instead. - **A capital
Son a program.** SUID or SGID is set but the matchingxisn't, so there's nothing to run. Usually you forgotx. (A capitalTon a directory, as in3770, is fine: it only means others have nox, which is exactly what you wanted.) - SGID on the directory but files still in the wrong group. It only affects files created after you set it. Fix the existing ones with
chgrp -R. - **Expecting
umaskchanges to stick.** They only last for the current shell. Put them in~/.bashrc. - A file root can't delete. Check
lsattrforiora.
Practice
- List every SUID or SGID program in
/usr/binin onefind.
Answer
$ find /usr/bin -perm /6000 -type f
/usr/bin/chsh
/usr/bin/mount
/usr/bin/passwd
/usr/bin/su
/usr/bin/umount
/usr/bin/sudo.ws
/usr/bin/chfn
/usr/bin/plocate
/usr/bin/fusermount3
/usr/bin/ssh-agent
/usr/bin/expiry
/usr/bin/chage
/usr/bin/newgrp
/usr/bin/ntfs-3g
/usr/bin/crontab
/usr/bin/gpasswd-perm /6000 means "any of these bits", so SUID or SGID. With - it would mean both.
- Create
/srv/projectsfor thedevsgroup: members can create files, new files land indevs, and members can't delete each other's files. Others get nothing. Test it as Ravi.
Answer
$ sudo mkdir /srv/projects $ sudo chown root:devs /srv/projects $ sudo chmod 3770 /srv/projects $ sudo -u ravi touch /srv/projects/plan.txt $ ls -ld /srv/projects drwxrws--T 2 root devs 4096 Oct 21 11:37 /srv/projects $ sudo ls -l /srv/projects total 0 -rw-r--r-- 1 ravi devs 0 Oct 21 11:37 plan.txt
- As
ubuntu, in a shell withumask 077, create a file and a directory in/srv/umask-laband show their permissions in numbers.
Answer
$ umask 077 $ touch secret.key $ mkdir vault $ stat -c "%a %n" secret.key vault 600 secret.key 700 vault
- Make
/srv/umask-lab/settings.confimpossible to change, prove that evensudocan't change it, then undo it.
Answer
$ echo "port=80" > settings.conf $ sudo chattr +i settings.conf $ echo "port=8080" | sudo tee settings.conf settings.conf: Operation not permitted (os error 1) port=8080 $ lsattr settings.conf ----i---------e------- settings.conf $ sudo chattr -i settings.conf
- What do the modes
2755and1770mean, in words?
Answer
2755: SGID plus rwxr-xr-x. On a program it runs with the file's group. On a directory, new files take the directory's group. 1770: sticky plus rwxrwx---. Owner and group can create files, others get nothing, and people can only delete their own files.
Cheat sheet
| Command | What it does |
|---|---|
rwsr-xr-x | SUID: runs as the owner |
rwxr-sr-x | SGID: runs with the group, or new files inherit the directory's group |
rwxrwxrwt | Sticky: only owners delete their files |
chmod u+s, g+s, +t | Add SUID, SGID, sticky |
chmod 4755, 2770, 1777 | The same with numbers |
find / -perm -4000 -type f | All SUID programs (security check) |
find / -perm /6000 -type f | SUID or SGID |
umask, umask -S | Show the umask |
umask 077 | Private by default (this shell only) |
lsattr file | Show attributes |
sudo chattr +i file / -i | Immutable on / off |
sudo chattr +a file / -a | Append-only on / off |