Robin.te.Hofstee

Linux File Permissions Explained

Robin te Hofstee9 min readViews2
Linux File Permissions Explained

A comprehensive guide to Linux file permissions — what they are, how the rwx model works, how to read and change permissions with chmod, chown and umask, plus special permissions like setuid, setgid and sticky bits.

Linux is a multi-user operating system, which means multiple people (and processes) can share the same machine at the same time. To keep everyone's files safe and to control who can do what, Linux uses a permission system built into every file and directory. This guide explains what file permissions are, how they work, and how to change them.

What Are File Permissions?

Every file and directory in Linux has three groups of permissions, one for each type of user:

CategoryMeaning
Owner (user)The user who created the file
GroupUsers in the file's assigned group
Others (world)Everyone else

And within each group there are three permissions:

PermissionSymbolValueOn a fileOn a directory
Readr4View file contentsList directory contents
Writew2Modify/delete fileCreate/delete files inside
Executex1Run the file as a programEnter (cd) the directory

If a permission is missing, it's shown as -.

Reading Permissions with ls -l

Run ls -l to see permissions on every file:

ls -l

Example output:

-rwxr-xr--  1 robin dev    2048 Aug 13 10:32 script.sh
drwxr-xr-x  2 robin dev    4096 Aug 13 10:30 logs/
-rw-------  1 robin dev     512 Aug 13 09:00 secret.key

Let's decode -rwxr-xr-- from left to right:

PartValueMeaning
Type-Regular file (d = directory, l = symlink)
OwnerrwxOwner can read, write, execute
Groupr-xGroup can read and execute, not write
Othersr--Everyone else can only read

So the trailing ten characters are the permission string: 1 type character + 3 groups of 3.

# Check permissions of a specific file or directory
ls -l /etc/shadow
ls -ld /var/log        # -d shows the directory itself, not its contents

Changing Permissions with chmod

chmod (change mode) is the main tool for editing permissions. There are two syntaxes: symbolic and numeric (octal).

Symbolic mode

You combine who (u user, g group, o others, a all) with an operator (+ add, - remove, = set exactly) and a permission.

chmod u+x script.sh     # add execute for the owner
chmod g-w file.txt      # remove write for the group
chmod o-r file.txt      # remove read for others
chmod a+x script.sh     # add execute for everyone
chmod u=rwx,g=rx,o=r file.txt   # set exactly: owner rwx, group rx, others r

Numeric (octal) mode

Each permission has a number: read = 4, write = 2, execute = 1. Add them up per group:

chmod 755 script.sh     # owner rwx (7), group r-x (5), others r-x (5)
chmod 644 file.txt      # owner rw- (6), group r-- (4), others r-- (4)
chmod 600 secret.key    # owner rw- (6), others nothing
chmod 777 public_dir    # everyone rwx (dangerous!)

A quick reference:

ValuePermissions
0---
1--x
2-w-
3-wx
4r--
5r-x
6rw-
7rwx
# Apply permissions recursively to a directory and everything inside
chmod -R 750 /srv/shared
 
# Show the current permissions as numbers
stat -c "%a %n" script.sh

Changing Ownership with chown and chgrp

Permissions are only useful if the file belongs to the right user and group.

# Change the owner of a file
sudo chown robin file.txt
 
# Change both owner and group at once
sudo chown robin:dev file.txt
 
# Change only the group
sudo chgrp dev file.txt
 
# Apply recursively
sudo chown -R robin:dev /srv/www

chown and chgrp usually require sudo because you're modifying files that may not belong to you.

Default Permissions with umask

When you create a new file, Linux applies default permissions that are then reduced by your umask. The standard defaults are 666 for files and 777 for directories.

# Show the current umask
umask
 
# The effective permissions = default - umask
# umask 022 -> files 644 (rw-r--r--), directories 755 (rwxr-xr-x)
 
# Set a stricter umask for this session (new files 600, dirs 700)
umask 077
touch newfile.txt
ls -l newfile.txt    # -rw-------  owner read/write only
 
# Make it permanent by adding the line to ~/.bashrc
echo "umask 027" >> ~/.bashrc

Special Permissions

Three special permissions go beyond the basic rwx model.

Setuid (s on owner's execute)

When a program has setuid set, it runs with the privileges of its owner, not the user who launched it. This is how sudo and passwd work.

# Add setuid (4 in the special position)
chmod 4755 program
 
# Symbolic equivalent
chmod u+s program
 
# Verify: look for 's' where the owner's 'x' would be
ls -l program        # -rwsr-xr-x
 
# Find all setuid binaries on the system (good security audit)
find / -perm -4000 -type f 2>/dev/null

Setgid (s on group's execute)

On a file, setgid runs it with the group of the file. On a directory, new files inherit the directory's group — essential for shared team folders.

# Add setgid (2 in the special position)
chmod 2755 shared_dir
chmod g+s shared_dir
 
# Files created here now inherit the folder's group automatically
ls -ld shared_dir     # drwxr-sr-x
 
# Find all setgid entries
find / -perm -2000 -type d 2>/dev/null

Sticky bit (t on others' execute)

On a directory, the sticky bit means only the file's owner (or root) can delete or rename files inside — even if the directory is world-writable. /tmp is the classic example.

# Add the sticky bit (1 in the special position)
chmod 1777 /tmp
chmod +t /tmp
 
# Verify: 't' replaces 'x' for others
ls -ld /tmp           # drwxrwxrwt

The special permissions combine with the normal ones in the four-digit octal notation:

chmod 1777 /tmp       # sticky bit + 777
chmod 4755 binary     # setuid + 755
chmod 2770 /srv/team  # setgid + 770

Permission Lookup Cheat Sheet

# View permissions
ls -l                    # normal listing
ls -ld folder            # a directory itself
stat file.txt            # detailed output including numeric mode
 
# Change permissions
chmod 644 file.txt       # numeric
chmod u+x,g-w file.txt   # symbolic
chmod -R 750 folder/     # recursive
 
# Change ownership
chown robin:dev file.txt
chgrp dev file.txt
 
# Defaults
umask

Common Mistakes to Avoid

  • Don't use chmod 777 on web folders. Any user (and any compromised process) can modify them.
  • Don't grant execute to files that don't need it. Principle of least privilege.
  • Don't leave setuid on binaries you don't understand. It's a privilege escalation vector.
  • Be careful with chown -R on system paths like /usr or /etc — you can brick your system.

Summary

Linux file permissions tell the system exactly who can read, write, and execute every file and directory. The three user groups (owner, group, others) and three permissions (rwx) combine into the permission string you see in ls -l. You control them with chmod (symbolic or numeric), chown/chgrp for ownership, and umask for defaults — plus the special setuid, setgid, and sticky bits for advanced cases. Get comfortable reading and setting permissions, and you'll be well on your way to mastering Linux security.

Share this post
Robin te Hofstee

Written by Robin te Hofstee

Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.

Nmap: The Complete Linux Network Scanner Tutorial

3

A comprehensive Nmap tutorial for Linux, covering installation, target specification, host discovery, port scanning techniques, service and OS detection, the Nmap Scripting Engine, timing and performance, output formats, and practical examples from the official reference guide.

How Git Works

1

Git is a distributed version control system that allows multiple people to collaborate on a project while maintaining a complete history of all change