A guide to understanding Linux ownership, octal modes, and why proper access control matters for security.

For a long time, whenever I hit a "Permission Denied" error, I had a reflex:

chmod 777 <file>

It worked every time, so I did not question it. But eventually, I realized that 777 is not a fix. It is an invitation for anyone on the system to read, modify, or even replace my files. In a production environment or a shared system, that is a massive security hole.

I decided to stop bypassing the system and actually learn how Linux access control works. Here is the breakdown of what I found.

1. The Power of Three

Every file and directory in Linux is governed by three classes of ownership:

  • User (u): The individual owner of the file.
  • Group (g): A specific set of users.
  • Others (o): Everyone else on the system.

Within these classes, there are three basic types of access:

  • r (Read): Gives access to read the content.
  • w (Write): Gives the ability to modify or change the content.
  • x (Execute): Gives the ability to execute the file.

Modifying Permissions: The Symbolic Method

To change these settings, we use the chmod command. The most intuitive way to do this is the symbolic method, which uses three simple operators:

  • + (Add): Grant a permission.
  • - (Remove): Take away a permission.
  • = (Set): Set exact permissions (overwriting existing ones).

Implementation Examples

Here is how those operators look in practice.

Adding Permissions If you have a script that you want to make executable for yourself and your group:

# Add execute permission to User and Group
chmod ug+x my_script.sh

Removing Permissions If you want to make sure "others" cannot read your sensitive configuration file:

# Remove read and write permissions from Others
chmod o-rw config.env

Setting Exact Permissions If you want to explicitly set a file to be read/write for the owner and read-only for everyone else, regardless of what the permissions were before:

# Set specific permissions for all classes at once
chmod u=rw,g=r,o=r index.html

Checking Your Changes You can always verify these changes by running the ls -l command. The output will show the ten-character string (like -rwxr-xr-x) that represents the file type and the three sets of permissions.

Files vs. Directories: A Crucial Distinction

Permissions do not behave the same way across the board. The "Execute" bit, in particular, changes meaning significantly for folders:

Read (r)

  • On Files: Gives access to read the content of the file.
  • On Directories: Gives access to list the contents inside the directory.

Write (w)

  • On Files: Gives the ability to modify or change the content of the file.
  • On Directories: Gives access to create, delete, or remove content (files and subdirectories).

Execute (x)

  • On Files: Gives the ability to execute the file as a program or script.
  • On Directories: Gives the access to traverse (enter) the directory.

2. Understanding the Octal Math

When you see chmod 755, you are looking at Octal Mode. Each permission is assigned a numeric value:

  • Read (r) = 4
  • Write (w) = 2
  • Execute (x) = 1

To get the number for a class, you simply add them up. For example, rwx (4+2+1) is 7, while r-x (4+1) is 5.

# Giving the owner full access and others only read/execute
chmod 755 script.sh
# Checking the result
ls -l script.sh
# Output: -rwxr-xr-x 1 user group 1024 Apr 28 10:00 script.sh

3. The Mystery of umask

Files and directories are not created with random permissions. Their initial access levels are determined by the umask command, which acts as a filter to remove specific permissions from a starting base value.

Finding Your Default

You can see your current mask by simply typing umask in your terminal.

  • The command typically displays a three-digit or four-digit octal number.
  • A value of 022 is the default for most Linux distributions.
  • This value is often defined globally in the /etc/login.defs file, but it can be changed to modify how the system handles new files.

How the Calculation Works

To determine the final permissions, the system takes a "base" value and subtracts the umask value from it at each corresponding position.

  • For Files: The base value is 666.
  • For Directories: The base value is 777.

A Practical Example

If your umask is set to the common 022:

  • Files: Subtracting 022 from 666 results in 644. This gives the owner read and write access (rw-), while the group and others only get read access (r — ). This is why most new files you create are not executable by default.
  • Directories: Subtracting 022 from 777 results in 755. This gives the owner full access (rwx), while the group and others can only list and enter the directory (r-x).
# Check your current shell's mask
umask
# Output: 022

Understanding umask is the key to knowing why your system looks the way it does the moment you save a new document or create a new project folder.

4. Special Permissions: SUID, SGID, and Sticky Bits

Beyond the common permissions, Linux includes three special bits that handle complex security scenarios. These allow for more granular control over how users interact with files and directories.

SUID (Set User ID)

The setuid permission makes a file execute with the permissions of its owner rather than the user who is actually running it.

  • Target: It can only be provided to a binary file and only to the user of that file.
  • The "Capital S" Rule: If a file has the suid bit but lacks the standard execute permission, it is represented by a capital S.
  • Kernel Security: It only works on binary files; the Linux kernel ignores it on shell scripts for security reasons.

Implementation Example:

# Set SUID on a binary
sudo chmod u+s /usr/local/bin/custom_tool
# Inspecting the 's' bit
ls -l /usr/local/bin/custom_tool
# Output: -rwsr-xr-x 1 root root 15K Apr 28 10:00 custom_tool

The s in the user's position indicates that when any user runs this, it executes with root privileges.

SGID (Set Group ID)

The setgid permission has two different effects depending on whether it is given to a file or a directory.

  • On Files: It executes the file with the permissions of the group that owns it.
  • On Directories: This is a powerful tool for collaboration. By placing this permission on a directory, all files and directories created inside will automatically inherit the group ownership of that parent directory.
  • Visual Representation: Just like suid, if the execute permission is missing, it appears as a capital S in the group segment.

Implementation Example:

# Set SGID on a shared directory
chmod g+s ./shared_project
# Inspecting the 's' bit in the group column
ls -ld ./shared_project
# Output: drwxrwsr-x 2 pyromancer developers 4096 Apr 28 10:00 shared_project

The Sticky Bit

The sticky bit (represented by the character t) is primarily used on directories to protect files from being deleted or moved by anyone but the owners of those files.

  • Placement: It is placed on the "others" permission segment.
  • Visual Representation: If the "others" class lacks execute permissions, it is shown as a capital T.
  • Impact: If a directory is empty, the bit has no effect. However, once content is added, it prevents the directory or its contents from being removed or moved by non-owners.

Implementation Example:

# Set the Sticky Bit
chmod +t ./public_folder
# Inspecting the 't' bit at the end
ls -ld ./public_folder
# Output: drwxrwxrwt 2 pyromancer pyromancer 4096 Apr 28 10:00 public_folder

The Special Permission Breakdown

You can apply a similar style to the special permissions section to keep it consistent:

SUID (Value: 4)

  • Effect: Executes with owner permissions.
  • Symbol: u+s.

SGID (Value: 2)

  • On Files: Executes with group permissions.
  • On Directories: New files inherit the parent group.
  • Symbol: g+s.

Sticky Bit (Value: 1)

  • Effect: Only owners can delete their own files.
  • Symbol: +t.

Example Command: chmod 4777 filename applies the suid bit (4) along with full read, write, and execute permissions (777) for all users.

5. Changing Ownership

Permissions are only half the battle. You also need to ensure the right people own the files.

  • Change User: sudo chown root rootshell (changes user to root and leaves group unchanged).
  • Change Group: sudo chgrp root rootshell (changes group to root and leaves user unchanged).
# Change owner to root and group to developers
sudo chown root:developers internal_report.pdf
# Verify ownership
ls -l internal_report.pdf
# Output: 
-rw-r----- 1 root developers 50K Apr 28 10:00 internal_report.pdf

Conclusion

The key realization for me was that permissions are checked by the kernel on every single operation. chmod 777 is not a fix. It is just turning off the security system because you do not have the key.

Now, instead of disabling access control, I try to understand the ownership and calculate the exact octal I need. It takes 10 seconds longer, but it keeps the system secure.

Documenting my journey into Linux and backend development. If you found this helpful, let me know what technical topic I should dive into next!