This week I learned about Unix file permissions and realized that I did not know anything about it. But apparently, it is not that difficult and an eye-opener to many behaviours of Unix systems.
1. File Permissions
You can check file permissions in a terminal with
ls -l file.txt
What you get is the following output:
-rw-r--r-- 1 davide davide 430 nov 25 01:56 file.txt
Let’s decode this line:
This is the symbolic representation of file permissions. The first character is a description of the file type. A dash means it is a normal file, but the following values are possible: (d)irectory, symbolic (l)ing, (p)ipes, (s)ockets, (c)haracter and (b)lock device. See Unix file types for more.
The first set represents the user class. The second set represents the group class. The third set represents the others class.
The permission classes are split between three different permissions:
- The read permission grants the permission to read a file or directory. Reading a directory means listing its files and showing the file names.
- The write permission grants the permission to write to a file. You can change the content of files and directories, as well as creating and deleting files.
- The execute permission is needed for running scripts and executable programs. For a directory, it allows to read the files.
So rw- means (read, write, no execute) and r-x means (read, no write, execute). Look at this like a binary representation: 110 and 101 for the above example.
The binary representation is important, because that is how permissions are set. The pattern above translated to binary is:
If you convert this binary number to the octal number system, you get:
And this is exactly what you need to set the permissions for a file:
chmod 644 file.txt
To show the octal representation for the permissions of a file, you can use
stat -c "%a %A" file.txt 644 -rw-r--r--
2. The SUID bit
There are special permission classes that can be set for specific programs. One of them is the set user ID, which only works with executable files. Whenever an executable with the SUID bit gets executed, the process executes with the rights of the owner of the file. Let us look at ping owned by root located in /bin/. First, let us look at the file permissions:
-rwsr-xr-x 1 root root 44168 mag 7 2014 /bin/ping
The file is owned by root and the group is root. Also, there is an S instead of an X in the permission string. This S stands for the SUID bit.
What you probably do not know about ping: It needs root permissions to run. The reason is that it uses raw sockets and you need root for doing that.
When you execute ping as a normal user, it executes with the rights of the owner, thus as root. I hope you can see how useful that is.
Of course you should not set the SUID on arbitrary root executables. Imagine if ping had a vulnerability in its code, and let you create files (e.g. logfiles). Those files would be created as root, and an attacker could create arbitrary files as root or find a way to do a privilege escalation attack.
Setting the SUID
To set the SUID bit, use
chmod u+s /bin/ping
You need either owner or root privileges to execute this, of course.
Correct use of SUID
To correctly use the SUID bit and prevent any security vulnerabilities, programs usually drop their root privileges after they executed the critical parts. This works by setting the user and group ID of the process to the effective user in your code. You can read about this here.