Nandishwar Singh

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

  1. Three extra bits
  2. SUID: run as the owner
  3. SGID: shared group
  4. Sticky bit: only delete your own
  5. The numbers for special bits
  6. umask: default permissions for new files
  7. Attributes: beyond permissions
  8. Common mistakes
  9. Practice
  10. 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.

BitShows asOn a programOn a directory
SUID (set user ID)s in the user's x placeRuns as the file's owner(no effect on Linux)
SGID (set group ID)s in the group's x placeRuns with the file's groupNew files inside get the directory's group
Stickyt 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/passwd

The 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

  1. Is su SUID? What about sudo?
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/chage

On 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

  1. 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/crontab

Sticky 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 /tmp

The 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.

ModeMeans
4755SUID program
2770Shared team directory (SGID)
1777A /tmp-style drop box (sticky)
3770SGID 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

  1. Make /srv/team15 both 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

  1. 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:

AttributeMeans
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

Practice

  1. List every SUID or SGID program in /usr/bin in one find.
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.

  1. Create /srv/projects for the devs group: members can create files, new files land in devs, 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
  1. As ubuntu, in a shell with umask 077, create a file and a directory in /srv/umask-lab and 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
  1. Make /srv/umask-lab/settings.conf impossible to change, prove that even sudo can'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
  1. What do the modes 2755 and 1770 mean, 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

CommandWhat it does
rwsr-xr-xSUID: runs as the owner
rwxr-sr-xSGID: runs with the group, or new files inherit the directory's group
rwxrwxrwtSticky: only owners delete their files
chmod u+s, g+s, +tAdd SUID, SGID, sticky
chmod 4755, 2770, 1777The same with numbers
find / -perm -4000 -type fAll SUID programs (security check)
find / -perm /6000 -type fSUID or SGID
umask, umask -SShow the umask
umask 077Private by default (this shell only)
lsattr fileShow attributes
sudo chattr +i file / -iImmutable on / off
sudo chattr +a file / -aAppend-only on / off