Linux File Permissions
May 23, 2025
Table of Contents
- Linux File Permissions
Linux File Permissions
As a Linux system administrator, there’s no concept more fundamental to security and system integrity than file permissions. It’s the bedrock upon which all access control is built, determining who can read, write, or execute every single file and directory on a Linux system. The seemingly cryptic rwx
and octal numbers felt like an ancient language.
Owner, Group, Others
At the core of Linux file permissions are three distinct entities, each with its own set of privileges:
-
Owner (User): This is typically the individual user who created the file or directory. They have the most control over their own files. When we create a script or a document, we are its owner, and by default, we have full control over it.
-
Group: Every file and directory is also associated with a group. This group can contain multiple users. The idea here is to facilitate shared access to files among a team or a specific set of users. For instance, if we’re working on a project with a team, we might create a “developers” group and assign files to that group, allowing all members of the group to collaborate on those files without giving access to everyone on the system. This simplifies management compared to assigning individual permissions to each user.
-
Others (World): This refers to everyone else on the system who is not the owner and not a member of the assigned group. These are the least privileged users. Permissions for “others” are typically set to be very restrictive for security reasons.
Read, Write, Execute
For each of these three entities (owner, group, others), three fundamental permissions can be granted or revoked:
- Read (
r
or4
):- For files: Allows viewing the contents of the file. If we don’t have read permission on a script, we can’t even see its lines of code.
- For directories: Allows listing the contents of the directory (i.e., seeing what files and subdirectories are inside using
ls
).
- Write (
w
or2
):- For files: Allows modifying, saving changes to, or deleting the file. Without write permission, we can’t edit a configuration file.
- For directories: Allows creating, deleting, or renaming files within that directory. This is a crucial distinction. we can have write permission to a file but not to its parent directory, meaning we can change the file’s content but not delete it or create new files in that directory.
- Execute (
x
or1
):- For files: Allows running the file as an executable program or script. If a script doesn’t have execute permission, it’s just a text file.
- For directories: Allows “entering” or traversing into the directory. Without execute permission on a directory, even if we know its path, I can’t
cd
into it or access its contents, even if we have read permission on the directory itself. This is a common pitfall for new administrators.
Peeking Behind the Curtain: ls -l
The first command I learned (and still use countless times a day) to understand file permissions is ls -l
. This “long listing” format provides a wealth of information, including the permission string.
ls -l myfile.sh
A typical output might look like this:
-rwxr--r-- 1 myuser mygroup 1234 Mar 28 10:00 myfile.sh
Let’s dissect the permission string (-rwxr--r--
):
- First Character (
-
): Indicates the file type.-
: Regular file.d
: Directory.l
: Symbolic link.c
: Character device file.b
: Block device file.p
: Named pipe (FIFO).s
: Socket.
- Next Nine Characters (
rwxr--r--
): These are grouped into three sets of three characters, representing permissions for:- Owner (
rwx
): In this example, the owner (myuser
) has read, write, and execute permissions. - Group (
r--
): The group (mygroup
) has read permission, but no write or execute. - Others (
r--
): All other users have read permission, but no write or execute.
- Owner (
This output gives me an immediate, clear picture of who can do what with myfile.sh
. If it’s a shell script that needs to be run, we immediately check if the x
bit is set for the relevant parties.
The Power of chmod
: Changing Permissions
The chmod
(change mode) command is my primary tool for modifying file permissions. It offers two main modes of operation: symbolic and numeric (octal).
Using Symbolic Mode: Intuitive Adjustments
Symbolic mode is often more intuitive for making specific, incremental changes to permissions. It uses u
(user/owner), g
(group), o
(others), and a
(all – owner, group, and others), combined with +
(add), -
(remove), or =
(set exactly).
- Add execute permission for the owner:
chmod u+x filename
If the file was
-rw-r--r--
, it becomes-rwxr--r--
. - Remove write permission for the group:
chmod g-w filename
If the file was
-rwxrwxrwx
, it becomes-rwxr-xrwx
. - Set read-only for others:
chmod o=r filename
This sets the permissions for others exactly to read, overriding any existing write or execute permissions for others. If the file was
-rw-rwxr-x
, it becomes-rw-rwx-r--
. - Set permissions for multiple entities simultaneously:
chmod u=rwx,g=rx,o= filename
This command sets full access (
rwx
) for the owner, read and execute (rx
) for the group, and no access (=
) for others. This is a powerful way to define precise permissions in one go.
we can find symbolic mode particularly useful when we need to quickly toggle a specific permission for a specific entity without affecting others, for example, making a script executable for myself (chmod u+x script.sh
).
Using Numeric (Octal) Mode: Absolute Control
Numeric (or octal) mode is my preferred method for setting precise, absolute permissions, especially for new files or when I need to define a standard permission set. Each permission (r
, w
, x
) has a numerical value:
r
(read) =4
w
(write) =2
x
(execute) =1
To get the octal value for each entity (owner, group, others), you sum the values of the desired permissions.
rwx
(read, write, execute) =4 + 2 + 1 = 7
rw-
(read, write, no execute) =4 + 2 + 0 = 6
r-x
(read, no write, execute) =4 + 0 + 1 = 5
r--
(read, no write, no execute) =4 + 0 + 0 = 4
You then combine these three numbers (one for owner, one for group, one for others) to form a three-digit octal number.
- Set user (rwx), group (r-x), others (r-x):
chmod 755 filename
This is a very common permission setting for executable scripts or web server content that needs to be readable and executable by others but only writable by the owner.
- Set user (rw-), group (r–), others (r–):
chmod 644 filename
This is the standard permission for most data files (like text documents, images) that should be readable by everyone but only writable by the owner.
- Set user (rwx), no access for group/others:
chmod 700 filename
This makes a file or directory private to the owner. Ideal for sensitive configuration files or personal scripts.
we use numeric mode extensively in scripts, deployment configurations, and when defining default permissions because it’s concise and defines the exact state of permissions.
Changing Permissions Recursively: -R
To change permissions for a directory and all its contents (subdirectories and files), I use the -R
(recursive) option with chmod
.
chmod -R 755 my_project_directory/
Caution: Using -R
with chmod
needs care. Applying 777
recursively, for instance, can expose your entire directory structure. I often use find
in conjunction with chmod
to set specific permissions for files and directories differently within a recursive operation (e.g., find . -type f -exec chmod 644 {} \;
for files and find . -type d -exec chmod 755 {} \;
for directories).
Changing Ownership: chown
and chgrp
While chmod
manages what can be done, chown
and chgrp
manage who can do it.
chown
: Changing Owners and Groups
The chown
(change owner) command allows me to change the owner and/or the group of a file or directory.
- Change only the owner:
chown newuser filename
Example:
chown alice report.txt
makesalice
the owner ofreport.txt
. - Change both owner and group:
chown newuser:newgroup filename
Example:
chown bob:devs project_report.doc
changes both the owner tobob
and the group todevs
. - Change only the group (using
chown
):chown :newgroup filename
If I only want to change the group owner, I can omit the user part but keep the colon. Example:
chown :webdevs index.html
. - Recursively change ownership:
chown -R newuser:newgroup directory/
Similar to
chmod -R
, this changes the owner and group for the directory and all its contents. This is crucial when deploying applications or moving user data.
chgrp
: Changing Group Ownership (Dedicated Command)
While chown
can change the group, chgrp
(change group) is a dedicated command specifically for changing the group owner of files and directories.
- Change group:
chgrp newgroup filename
Example:
chgrp managers financial_data.xlsx
. - Recursively change group:
chgrp -R newgroup directory/
we often use chown
when we need to set both owner and group, and chgrp
when we only need to adjust the group affiliation, though technically chown :newgroup
achieves the same result as chgrp newgroup
.
Special Permissions: Beyond the Basics
Beyond the standard rwx
permissions, Linux offers special permissions that add layers of functionality and security. These are represented by an s
(SetUID/SetGID) or t
(Sticky Bit) in the ls -l
output where an x
would normally be, and have an additional leading digit in octal mode.
1. SetUID (s
on user execute bit)
When the SetUID bit is set on an executable file, any user who runs that file will execute it with the permissions of the file’s owner, not their own. This is commonly used for system utilities.
- How it looks:
ls -l /usr/bin/passwd
might show-rwsr-xr-x
. Thes
replaces thex
for the owner. - Setting it:
chmod u+s filename # Or in octal: chmod 4755 filename (the '4' prefix indicates SetUID)
- My primary use case: The most famous example is
/usr/bin/passwd
. When a regular user executespasswd
to change their own password, thepasswd
executable needs write access to/etc/shadow
(where encrypted passwords are stored). Regular users don’t have this permission. However, becausepasswd
has the SetUID bit set and is owned byroot
, it runs withroot
’s privileges, allowing it to modify/etc/shadow
.
Security Implication: SetUID programs are a potential security risk if not carefully managed, as a bug in a SetUID program could allow a malicious user to gain root privileges. we should be extremely cautious when granting SetUID permissions to any custom scripts or programs.
2. SetGID (s
on group execute bit)
The SetGID bit has two distinct behaviors depending on whether it’s applied to a file or a directory:
- On files: Similar to SetUID, users executing the file will run it with the permissions of the file’s group owner.
- How it looks:
-rwxrwsr-x
(thes
replaces thex
for the group). - Setting it:
chmod g+s filename # Or in octal: chmod 2755 filename (the '2' prefix indicates SetGID)
- How it looks:
- On directories: This is where SetGID truly shines for collaborative environments. When SetGID is applied to a directory, any files or subdirectories created within that directory will inherit the group ownership of the parent directory, rather than the primary group of the user who created them.
- How it looks:
drwxrwsr-x
(thes
replaces thex
for the group on a directory listing). - Setting it:
chmod g+s directory/ # Or in octal: chmod 2775 directory/
- My primary use case: I use SetGID directories extensively for shared project folders. If a group
devs
owns a directory/project/code
and this directory has SetGID set, then every file and subdirectory created by any member of thedevs
group within/project/code
will automatically be owned by thedevs
group. This ensures all team members have proper group access to new files without needing tochgrp
them manually.
- How it looks:
3. Sticky Bit (t
on others execute bit)
The Sticky Bit is primarily used on directories to control file deletion. When set on a directory, only the owner of a file (or the directory’s owner, or root) can delete or rename files within that directory, even if they have write permission to the directory itself.
- How it looks:
drwxrwxrwt
(thet
replaces thex
for others on a directory listing). - Setting it:
chmod +t directory/ # Or in octal: chmod 1777 directory/ (the '1' prefix indicates Sticky Bit)
- My primary use case: The most common example is the
/tmp
directory. Users can create files in/tmp
because it has write permission for everyone (777
), but because the Sticky Bit is also set, one user cannot delete another user’s temporary files. This prevents malicious deletion of other users’ data in shared temporary spaces.
Default Permissions: umask
When a new file or directory is created, it doesn’t automatically get 777
or 666
permissions. Instead, default permissions are determined by a setting called umask
. umask
acts as a “permission mask” that removes permissions from the maximum possible permissions.
- Maximum permissions for a file:
666
(rw-rw-rw-) – no execute by default for security. - Maximum permissions for a directory:
777
(rwxrwxrwx) – executable by default as you need execute to traverse.
To calculate the effective permission, you subtract the umask
value from the maximum.
- Check current umask:
umask # Output might be 0022 or 022
The leading
0
indicates octal. The022
means:- Owner: no bits masked (0)
- Group:
w
(2) bit masked - Others:
w
(2) bit masked
- Applying umask 022:
- For files:
666 - 022 = 644
(rw-r–r–) - For directories:
777 - 022 = 755
(rwxr-xr-x)
- For files:
These are very common and sensible default permissions.
- Set a new umask (temporarily):
umask 007
This would make new files
660
(rw-rw—-) and new directories770
(rwxrwx—), effectively giving group members full access but denying any access to others. I useumask
in shell scripts or environment configurations when specific default permissions are required for files created by a service or process.
Conclusion: The Bedrock of Linux Security
File permissions are not just an administrative chore; they are the very foundation of security in a multi-user Linux environment. My journey through understanding rwx
, octal values, chmod
, chown
, chgrp
, and special permissions has been transformative. It’s given me the power to:
- Enforce the Principle of Least Privilege: Granting users and services only the permissions they absolutely need.
- Protect Sensitive Data: Restricting access to configuration files, private keys, and user data.
- Facilitate Collaboration: Using groups and SetGID to enable seamless teamwork on shared resources.
- Prevent Malicious Actions: Mitigating risks of unauthorized modification or execution.
- Debug Access Issues: Quickly identify why a user or application can’t access a file.
Mastering file permissions requires practice, attention to detail, and a constant awareness of security best practices. It’s a skill that pays dividends daily, ensuring the stability, security, and integrity of every Linux system I manage. For any aspiring system administrator, this is one of the first and most important mountains to climb.