Search

Linux File Permission Confusion

0 views

Decoding the Permissions String

When you run ls -l you see a ten‑character string that looks like drwxr-xr--. Those letters are the gatekeepers that decide whether a user can read, write, or execute a file. The string breaks into three groups of three plus a leading character that tells you the file type. The first character is a marker: d means directory, l a symbolic link, p a named pipe, s a socket, and so on. The next nine characters are the permissions, split into user (owner), group, and other. Each group uses r for read, w for write, and x for execute. A dash indicates the permission is absent.

Consider this example output:

Prompt
$ ls -l</p> <p>drwxrwxrwx 1 reegen reegen 4096 Jan 22 10:05 dropbox</p> <p>drwx------ 1 reegen reegen 4096 Dec 6 8:50 private_logs</p> <p>-rw-r--r-- 1 reegen reegen 9663 Oct 8 16:03 public</p> <p>-rw------- 1 reegen reegen 8925 Jan 12 11:17 secret</p>

Reading the first line, dropbox is a directory that anyone can read, write, or enter. The second line, private_logs, is a directory that only the owner can access; the rest of the world is locked out. The third line shows a file readable by everyone but writable only by its owner. The last line is the most restrictive: only the owner can read the file; no one else has any rights.

These permissions are not arbitrary. The kernel enforces them by following a strict hierarchy: owner first, then group, then others. The kernel does not scan all three categories for a match; it stops as soon as a decisive rule is found. This subtlety can trip administrators who assume that a read bit set for “others” will override a missing read bit for the group or owner. In practice, the kernel checks each category in order and, if it finds that the user matches that category, it consults only the corresponding bits.

Take this scenario:

Prompt
$ id</p> <p>uid=1000(doug) gid=1000(doug) groups=1000(doug),1001(web)</p> <p>$ ls -l foo.html</p> <p>-rw-r----- 1 www-data web 9663 Oct 8 16:03 foo.html</p>

Doug is not the owner but belongs to the group web. The group read bit is set, so Doug can read the file. Now change the file's permissions to:

Prompt
$ ls -l bar.html</p> <p>-rw----r-- 1 www-data web 19838 Sep 17 4:22 bar.html</p>

Doug would intuitively think that the “others” read bit gives him access. The kernel, however, sees that Doug is a member of the group web and checks only the group bits, which have no read permission. The file remains unreadable for Doug. This illustrates the importance of understanding the lookup order.

Because the owner’s permissions trump the group and others, it is possible to set up a file where the owner has no access but the group or others do. This is rare but valid, and it shows that you must think in terms of the hierarchy rather than the presence of any bit. If you need to lock yourself out from a file you own, you can simply clear the owner bits: chmod u-rwx secret. Once the owner has no rights, the group or others become the gatekeepers.

Beyond the basic rwx bits, two additional flags - setuid and setgid - modify execution behavior. The setuid bit ( in the user position) makes a program run with the file owner’s UID instead of the caller’s. The setgid bit ( in the group position) forces execution with the file group ID. These bits are crucial for privileged tasks like password changes, but they also open a window for privilege escalation if misused. An attacker who can place a setuid program in a directory readable by many can run that program with elevated rights. That is why many distributions strip setuid from files that are world‑writable.

Understanding these rules is the first step toward building a robust security posture. The kernel will obey the hierarchy exactly; there is no room for guesswork. Knowing this lets you predict the outcome of permission changes before they take effect, saving time and reducing mistakes.

Practical Permission Management: Group Tricks and Exceptions

Once you grasp how the kernel resolves permissions, you can leverage that knowledge to craft policies that balance accessibility with safety. One of the most common use cases is restricting a command to a specific group while leaving it available to everyone else. A classic example is the compiler gcc on a multi‑user workstation. You might want only developers to compile code, but let all users run the resulting binaries.

Start with the default state:

Prompt
$ ls -l /usr/bin/gcc</p> <p>-rwxr-xr-x 1 root root 74088 Sep 23 15:13 /usr/bin/gcc</p>

Root is the owner, and everyone else has read and execute rights. To grant exclusive compilation rights to a devel group, create the group and change the file’s group owner:

addgroup devel

chgrp devel /usr/bin/gcc

$ ls -l /usr/bin/gcc

-rwxr-xr-x 1 root devel 74088 Sep 23 15:13 /usr/bin/gcc

Now remove execute permission from the “others” category so only root and devel can run the compiler:

chmod o-x /usr/bin/gcc

$ ls -l /usr/bin/gcc

-rwxr-xr-- 1 root devel 74088 Sep 23 15:13 /usr/bin/gcc

At this point, developers in the devel group can compile; normal users cannot. If the group membership grows, you only need to add users to devel; no permission changes are necessary.

Sometimes you want the opposite: allow almost everyone to use a tool but exclude a small list of users. Instead of adding every legitimate user to a group, create an exclusion group called jerks and remove the group bits:

addgroup jerks

chgrp jerks /usr/bin/gcc

$ ls -l /usr/bin/gcc

-rwxr-xr-x 1 root jerks 74088 Sep 23 15:13 /usr/bin/gcc

chmod g-rx /usr/bin/gcc

$ ls -l /usr/bin/gcc

-rwx---r-x 1 root jerks 74088 Sep 23 15:13 /usr/bin/gcc

Now gcc runs for anyone who is not in jerks. Managing a short list of exclusions is often simpler than maintaining a large inclusion group.

These examples illustrate a powerful principle: permission changes affect only the most specific match. By choosing whether to enable or disable bits in the owner, group, or others categories, you can shape who can do what with minimal administrative overhead. Remember that each chmod command affects all files in a directory only if you apply it recursively. Be careful with -R; a single mistake can grant broad access or strip it entirely.

In practice, combine permission logic with access control lists (ACLs) for finer granularity. ACLs let you grant rights to individual users or groups beyond the basic owner/group/others trio. For example, you could set a read permission for a single user on a directory that otherwise denies all others. Use the setfacl and getfacl tools to manage these rules. ACLs are especially useful on systems where file sharing is frequent and group membership alone is too coarse.

When you apply these techniques, keep the following checklist in mind: identify the resource, decide the required audience, map that audience to the correct permission tier, and use chmod or ACLs to enforce it. Test with a non‑privileged user to confirm the rule behaves as expected. Repeat the process whenever you add or remove users or change system roles.

By mastering the lookup order and the practical tools for setting and adjusting permissions, you can maintain tight security without sacrificing usability. The kernel’s strict hierarchy may feel rigid, but with thoughtful configuration it becomes a powerful ally in protecting your files and services.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles