ArticlesLinuxOpen Source Software

Understanding the Linux / Unix file permissions

If you are new to the Linux world, you might find yourself scratching your head when it comes to file permissions. Linux file systems use a file permission system implemented by the much older Unix systems.

By looking at the permissions of a file or a directory, the first column represents the permissions, which show a bunch of letters or dashes:

ck@linux ~ $ ls -la /tmp/myfile 
-rw-rw-r-- 1 ck ck 0 Sep 11 10:36 /tmp/myfile

The permission column supports 10 characters. The first character is used to indicate the type of file (such as a directory or link), the nine other characters are split into a group of three (User – Group – Others) and represent the actual file permission. Each character group has a set of permissions (Read – Write – Execute).

Linux (Unix) file permissions

User – Group – Others

The Unix permissions are based on three different types of access:

  • User: Represents the owner of the file or directory. What permissions should the owner have?
  • Group: Represents the group the file belongs to. In most cases the user is a member of this group. What permissions should the group have?
  • Others: Represents all other users. What permissions should all other users have on this file or directory?

Read – Write – Execute

Each type of access (User, Group, Others) have their own permissions. There are three types of permissions on files:

  • Read: Allows the file to be read by the selected access type
  • Write: Allows the file to be (over-) written by the selected access type
  • Execute: Allows the file to be executed by the selected access type.
    Note: On directories the execution permission is needed to change into the directory.

Binary permission numbers: 4, 2, 1

Surely you have seen and heard about the permission "numbers", such as 644, 666, 777 etc. when changing file and directory permissions. Also web-developers come across these permissions when using FTP or SFTP to upload files and change permissions. These numbers represent the summarized binary number for file permissions.

The binary numbers are set the following way:

  • Read: 4
  • Write: 2
  • Execute: 1

Let's take a simple file as an example:

geek@linux ~ $ ls -la /tmp/myfile 
-rw-rw-r-- 1 geek geek 0 Sep 11 10:36 /tmp/myfile

Let's start with the user/owner. The user geek has read and write permissions. So we add 4 (read) and 2 (write) = 6. This number represents the first permission for the user/owner.

For the next access type (group) we also see read and write permissions. Again 4 + 2 = 6.

And finally the last access type (others) we see only a read permission, meaning just a 4.

With the permissions number for each access types we come up with : 664 .

Linux / Unix file permissions in binary numbers.
Linux / Unix file permissions in binary numbers.

Changing permissions

File permissions can be changed using the chmod command. The command supports two syntaxes:

1. Using the permissions on an access type (e.g. user)

Example: Adding write permission to others:

geek@linux ~ $ chmod o+w /tmp/myfile

geek@linux ~ $ ls -la /tmp/myfile
-rw-rw-rw- 1 geek geek 0 Sep 11 10:36 /tmp/myfile

Example: Removing write permission for group:

geek@linux ~ $ chmod g-w /tmp/myfile

geek@linux ~ $ ls -la /tmp/myfile
-rw-r--rw- 1 ckadm ckadm 0 Sep 11 10:36 /tmp/myfile

2. Using the binary number for the permission across all access types.

Example: Setting read-write permissions to all access types:

geek@linux ~ $ chmod 666 /tmp/myfile

geek@linux ~ $ ls -la /tmp/myfile
-rw-rw-rw- 1 ckadm ckadm 0 Sep 11 10:36 /tmp/myfile

Example: Setting read-write permission to user, read to group, none to others:

geek@linux ~ $ chmod 640 /tmp/myfile

geek@linux ~ $ ls -la /tmp/myfile
-rw-r----- 1 ckadm ckadm 0 Sep 11 10:36 /tmp/myfile

File types

As mentioned above, the first of the ten permission characters is used to indicate a Unix file type.

The most common "different" file type is a directory. Looking at the permissions of a directory quickly shows that the first character is a "d", representing a directory:

geek@linux ~ $ mkdir /tmp/mydirectory

geek@linux ~ $ ls -la /tmp | grep mydirectory
drwxrwxr-x  2 geek geek   4096 Sep 11 10:36 mydirectory

Other special file types (non-conclusive list):

  • – (dash): Regular file (seen on every normal file)
  • d: Directory
  • b: Block device
  • l: Symbolic link
  • s: Socket

Special permissions (setuid, setgid, sticky bit)

Besides indicating a file type, such as directory, the first character can also show whether or not special permissions have been applied to a file or directory. These special permissions are the following.

setuid bit (4)

Additional setuid permission allows a user to run a program with the same permissions as the owner of the file.

To set setuid as additional permission:

geek@linux ~ $ chmod 4755 /tmp/myprogram 

geek@linux ~ $ ls -la /tmp/myprogram
-rwsr-xr-x 1 geek geek 26 Sep 11 12:54 /tmp/myprogram

The execution bit for the user has changed from x to s.

A typical example and real-world use case for the setuid is the passwd command:

geek@linux:~$ ls -la /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Nov 29  2022 /usr/bin/passwd

Without the setuid bit applied, a regular user would not be able to execute passwd and change its own password.

setgid bit (2)

Additional setgid permission allows a user to run a program with the same permissions as the group of the file.

If set on a directory, the behaviour of setgid changes. Instead of executing a program, setgid allows a user to create new files in that directory which then belong to the same group as the directory.

geek@linux ~ $ mkdir /tmp/geek
geek@linux ~ $ chmod 2777 /tmp/geek

geek@linux ~ $ ls -la /tmp/|grep geek
drwxrwsrwx  2 geek geek   4096 Sep 11 13:15 geek

tester@linux:~$ touch /tmp/geek/hello.txt

tester@linux:~$ ls -la /tmp/geek/hello.txt
-rw-rw-r-- 1 tester geek 0 Sep 11 13:17 /tmp/geek/hello.txt

sticky bit (1)

The sticky bit is rarely used but is important for world-writeable directories, such as the /tmp directory. As the /tmp directory is writeable by any user, a file could be created by one user and then deleted by another user. With the sticky bit set, the file system allows modification and deletion of a file only by the file owner, the directory owner or root user.

The sticky bit permission can be seen at the very end of the ten permission characters (with a t instead of x):

geek@linux ~ $ touch /tmp/this-file-is-owned-by-geek.txt
geek@linux ~ $ chmod 666 /tmp/this-file-is-owned-by-geek.txt

tester@linux:~$ rm /tmp/this-file-is-owned-by-geek.txt 
rm: cannot remove '/tmp/this-file-is-owned-by-geek.txt': Operation not permitted

Common mistakes

The most common mistake is when (non-aware) users want to just grant read write permissions to everyone, e.g. for a web application handling uploads. In many cases a general chmod 777 is then applied. But as we've described above, the additional execution bit is only needed for directories, not for regular files. The correct way to do this would be chmod 666 for regular files and chmod 777 for directories. However this is considered a security risk and you should stick to setting permissions for user and group only.

Claudio Kuenzler
Claudio has been writing way over 1000 articles on his own blog since 2008 already. He is fascinated by technology, especially Open Source Software. As a Senior Systems Engineer he has seen and solved a lot of problems - and writes about them.

You may also like

Comments are closed.

More in:Articles