Understand and Apply Special Permissions (SUID, SGID, Sticky Bit)
In this step, you will explore special permissions in Linux: SUID (Set User ID), SGID (Set Group ID), and the Sticky Bit. These permissions provide enhanced control over file execution and directory behavior.
Special permissions are represented by an additional digit in the octal permission mode, placed before the standard three digits (owner, group, others).
- SUID (Set User ID):
- Octal value: 4
- Effect on files: When an executable file with SUID is run, it executes with the permissions of the file's owner, not the user who ran it. This is commonly used for programs that need elevated privileges to perform certain tasks, like the
passwd command (which needs to write to /etc/shadow, a file owned by root).
- In
ls -l output: An s appears in place of the owner's x (execute) permission. If the owner does not have execute permission, an uppercase S appears.
- SGID (Set Group ID):
- Octal value: 2
- Effect on files: Similar to SUID, but the executable runs with the permissions of the file's group owner.
- Effect on directories: Files and subdirectories created within an SGID-enabled directory inherit the group ownership of that directory, rather than the primary group of the user who created them. This is very useful for shared directories where all files should belong to a specific group.
- In
ls -l output: An s appears in place of the group's x (execute) permission. If the group does not have execute permission, an uppercase S appears.
- Sticky Bit:
- Octal value: 1
- Effect on files: No effect.
- Effect on directories: Users can create files in the directory, but they can only delete or rename files that they own. This prevents users from deleting or moving other users' files in a shared directory (e.g.,
/tmp).
- In
ls -l output: A t appears in place of others' x (execute) permission. If others do not have execute permission, an uppercase T appears.
Let's demonstrate these special permissions.
SUID Example
We'll create a simple C program that attempts to read a restricted file.
First, create a file that only root can read:
sudo touch ~/project/secret_data.txt
sudo chmod 600 ~/project/secret_data.txt
sudo chown root:root ~/project/secret_data.txt
Verify its permissions:
ls -l ~/project/secret_data.txt
Output:
-rw------- 1 root root 0 Jun 6 17:36 /home/labex/project/secret_data.txt
Now, create a C program read_secret.c that tries to read this file:
nano ~/project/read_secret.c
Paste the following code into read_secret.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
FILE *fp;
char buffer[256];
printf("Attempting to read /home/labex/project/secret_data.txt...\n");
fp = fopen("/home/labex/project/secret_data.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
printf("Successfully read file.\n");
return 0;
}
Save and exit nano (Ctrl+S, Ctrl+X).
Compile the program:
gcc ~/project/read_secret.c -o ~/project/read_secret
Now, try to run it as labex:
~/project/read_secret
You should see an "Error opening file: Permission denied" message, as labex does not have read access to secret_data.txt.
Now, let's make read_secret owned by root and set the SUID bit.
sudo chown root:root ~/project/read_secret
sudo chmod u+s ~/project/read_secret
Verify the permissions:
ls -l ~/project/read_secret
Output:
-rwsr-xr-x 1 root root 17704 Jun 6 01:02 /home/labex/project/read_secret
Notice the s in the owner's permission set. Now, run the program again as labex:
~/project/read_secret
This time, it should successfully read the file (though it's empty, so no content will be printed, but the "Successfully read file." message indicates success). This is because the SUID bit made the program run with root's permissions.
SGID Example (on Directory)
Let's create a shared directory and a new group.
sudo groupadd shared_group
sudo mkdir ~/project/shared_dir
sudo chown labex:shared_group ~/project/shared_dir
sudo chmod 770 ~/project/shared_dir
Now, set the SGID bit on shared_dir:
sudo chmod g+s ~/project/shared_dir
Verify the permissions:
ls -ld ~/project/shared_dir
Output:
drwxrws--- 2 labex shared_group 6 Jun 6 01:02 /home/labex/project/shared_dir
Notice the s in the group's permission set.
Now, create a file inside shared_dir:
touch ~/project/shared_dir/new_file.txt
Check the ownership of new_file.txt:
ls -l ~/project/shared_dir/new_file.txt
Output:
-rw-r--r-- 1 labex shared_group 0 Jun 6 01:02 /home/labex/project/shared_dir/new_file.txt
Even though labex's primary group is labex, the new_file.txt inherited the shared_group group ownership from shared_dir due to the SGID bit.
Sticky Bit Example
The /tmp directory is a classic example of a directory with the sticky bit set. Let's create a similar directory.
sudo mkdir ~/project/public_upload
sudo chmod 1777 ~/project/public_upload
The 1 in 1777 is the octal value for the sticky bit. 777 grants full permissions to owner, group, and others.
Verify the permissions:
ls -ld ~/project/public_upload
Output:
drwxrwxrwt 2 root root 6 Jun 6 01:02 /home/labex/project/public_upload
Notice the t in others' permission set.
Now, let's simulate another user creating a file in this directory. Since we only have labex user, we'll create a file as labex and then try to delete it after changing its ownership to root (simulating another user).
Create a file as labex:
touch ~/project/public_upload/labex_file.txt
Change its ownership to root:
sudo chown root:root ~/project/public_upload/labex_file.txt
Now, try to delete labex_file.txt as labex:
rm ~/project/public_upload/labex_file.txt
You will see a prompt asking if you want to remove the write-protected file, and after confirming with y, you'll get an "Operation not permitted" error. This is because the sticky bit prevents users from deleting files they don't own within that directory, even though labex has write permission on the public_upload directory. Only root or the owner of labex_file.txt (root in this case) can delete it.
To clean up, you'll need sudo to remove labex_file.txt:
sudo rm ~/project/public_upload/labex_file.txt
Cleaning Up
Remove the created files and directories, and the user/group:
sudo rm -f ~/project/secret_data.txt ~/project/read_secret.c ~/project/read_secret
sudo rm -rf ~/project/shared_dir ~/project/public_upload
sudo groupdel shared_group