Cyber Security • Systems and Endpoint Security

Linux Permissions & sudo — Explain Linux permission model (rwx) and sudo conceptually

Understanding how Unix discretionary access controls and privilege escalation govern system security.

A protected digital shield with binary code and a secure lock for cyber security
Inside this lesson 10 sections 5 questions 8 figures

SECTION 1

Historical Context & Motivation

The Linux permission model did not emerge in a vacuum; it is a direct descendant of the access-control mechanisms designed for Unix at Bell Labs in the early 1970s. At that time, computing resources were scarce and expensive, and multiple users shared a single machine through time-sharing terminals. The fundamental challenge was straightforward yet critical: how do you allow dozens of users to coexist on the same file system without accidentally — or maliciously — reading, modifying, or deleting each other's data? The discretionary access control (DAC) model that Ken Thompson and Dennis Ritchie devised was elegant in its simplicity, encoding ownership and permissions into a compact set of bits for every file and directory on the system.

As Unix proliferated through universities and research labs during the 1970s and 1980s, the need for administrative privilege escalation became apparent. System administrators needed a controlled way to grant ordinary users temporary superuser capabilities without sharing the root password. This led to the development of sudo (superuser do), which introduced fine-grained delegation of root-level commands. Together, the rwx permission bits and sudo form the bedrock of Linux endpoint security, and understanding them is essential for any security practitioner working with Linux-based infrastructure — which, as of today, powers the vast majority of web servers, cloud instances, and embedded devices worldwide.

1969–1971 • Birth of Unix at Bell Labs

Ken Thompson and Dennis Ritchie develop Unix with a multi-user, hierarchical file system. Every file receives an inode containing owner, group, and permission metadata — establishing the rwx model.

1980 • sudo is Created at SUNY Buffalo

Bob Coggeshall and Cliff Spencer write the first version of sudo, allowing delegated execution of commands as root. The concept of least-privilege escalation is formalized.

1991 • Linux Kernel 0.01 Released

Linus Torvalds releases the first Linux kernel, inheriting the Unix permission model wholesale. Linux rapidly becomes the dominant open-source operating system for servers.

1994 • Todd C. Miller Maintains sudo

Todd Miller takes over sudo maintenance, adding /etc/sudoers policy files, logging, and security hardening. Modern sudo becomes the standard privilege-escalation tool across Linux distributions.

2000s–Present • POSIX ACLs, SELinux, and Beyond

Extended ACLs, SELinux mandatory access controls, and Linux capabilities supplement — but do not replace — the foundational rwx model. The traditional permission bits remain the first line of defense on every Linux system.

The central question this lesson addresses is: How does Linux determine who can read, write, or execute a resource, and how does sudo enable controlled privilege escalation without compromising the principle of least privilege? Answering this requires a precise understanding of permission bits, ownership semantics, and the sudoers policy mechanism.

SECTION 2

Core Principles & Definitions

Linux access control rests on a small number of foundational concepts that interact to produce a robust security posture. Every file and directory in the Linux file system carries metadata — stored in the inode — that specifies exactly who may interact with the resource and in what manner. This metadata includes the owning user (UID), the owning group (GID), and a mode field encoded as a bitmask of permission flags. Because each user process runs with a specific UID and set of GIDs, the kernel can evaluate access requests deterministically at every system call.

1

Ownership Triad

Every file has exactly one owner user and one owner group. All other users fall into the others category. Access decisions cascade: user → group → others, with the first match winning.
2

Permission Bits (rwx)

Three permission types exist: read (r) allows examining contents; write (w) allows modification; execute (x) allows running a file as a program or traversing a directory.
3

Principle of Least Privilege

Users and processes should operate with the minimum set of permissions necessary to perform their tasks. This limits the blast radius of compromised accounts or buggy software.
4

Superuser (root) & UID 0

The root account (UID 0) bypasses all DAC checks. Because unrestricted root access is dangerous, sudo provides policy-controlled, audited, temporary privilege escalation instead of sharing the root password.
5

Discretionary vs. Mandatory AC

The rwx model is discretionary — the file owner decides who gets access. Mandatory access controls (SELinux, AppArmor) layer on top, enforcing system-wide policies that even root cannot override.
✦

KEY TAKEAWAY

Think of Linux file permissions like a building's key-card system. The owner is the tenant who controls their office door, the group represents the department with shared lab access, and others are visitors in the lobby. sudo is like a temporary master key issued by building security: it grants you full access, but only for a specific task, and every use is logged in the security ledger.

SECTION 3

Visual Explanation — The Permission Bit Layout

The output of ls -l displays a ten-character string such as -rwxr-xr--. The first character indicates the file type (regular file, directory, symlink, etc.), and the remaining nine characters are three groups of three permission bits corresponding to user, group, and others, respectively. The following diagram decodes this string, mapping each character to its semantic meaning and its octal value.

Decoding the ls -l Permission String-File Typerwxr-xr--User (Owner)rwx = 4+2+1 = 7Groupr-x = 4+0+1 = 5Othersr-- = 4+0+0 = 4Octal Representation:-rwxr-xr-- → 0754Permission Bit ValuesBitSymbolOctal ValueBinaryEffect on FilesReadr4100View contentsWritew2010Modify / deleteExecutex1001Run as program
The ten-character permission string from ls -l decoded into its file-type indicator (position 0), user/group/others triplets (positions 1–9), and the equivalent octal notation. Each permission bit maps to a binary value that can be summed for the octal digit.

When a process issues a system call such as open() or execve(), the kernel consults the requesting process's effective UID and GIDs against the file's inode metadata. The evaluation follows a strict hierarchy: if the process's UID matches the file owner, only the user permission triplet is checked — the group and others bits are ignored entirely. If the UID does not match but one of the process's GIDs matches the file's group, the group triplet applies. Otherwise, the others triplet is used. This first-match-wins behavior means that a file owner can paradoxically lock themselves out by setting user permissions to --- even though group or others might have read access; the kernel will apply the owner's empty permission set and deny the request.

SECTION 4

The Bitmask Mechanism — Octal Encoding & umask

The nine permission bits for user, group, and others are stored internally as a single 9-bit field within the inode's mode value. Because three bits map naturally to a single octal digit (values 0–7), Unix adopted octal notation as the standard compact representation. The full mode also contains additional bits — the setuid, setgid, and sticky bits — encoded in a leading octal digit, giving a four-digit octal representation such as 0755 or 4755.

OCTAL PERMISSION ENCODING

Octaldigit=r×4+w×2+x×1Octal digit = r × 4 + w × 2 + x × 1

Where r, w, x ∈ {0, 1}. For example, rwx = 1×4 + 1×2 + 1×1 = 7; r-x = 1×4 + 0×2 + 1×1 = 5.

UMASK — DEFAULT PERMISSION MASK

Effectivepermissions=BasepermissionsAND(NOTumask)Effective permissions = Base permissions AND (NOT umask)

Files default to 0666 and directories to 0777. With a common umask of 0022, a new file receives 0666 AND NOT(0022) = 0644 (rw-r--r--), and a new directory receives 0755 (rwxr-xr-x).

SPECIAL PERMISSION BITS

Mode=[special][user][group][others]=SUGO(4octaldigits)Mode = [special][user][group][others] = SUGO (4 octal digits)

The special octal digit encodes: setuid (4) — process runs as file owner; setgid (2) — process runs as file group or new files inherit directory group; sticky (1) — only the file owner can delete entries in that directory (e.g., /tmp).

⚠

Security Implication

The setuid bit on an executable is one of the most security-sensitive features in Linux. A setuid-root binary like /usr/bin/passwd allows unprivileged users to change their own passwords by temporarily running as root. If a setuid-root binary has a buffer overflow vulnerability, an attacker can obtain full root access. This is why modern distributions minimize setuid binaries and increasingly rely on Linux capabilities instead.

SECTION 5

Directory Permissions & sudo in Depth

A common source of confusion is that the permission bits carry different semantics for directories than for regular files. For a directory, read (r) means the ability to list file names (run ls), write (w) means the ability to create, rename, or delete entries within the directory, and execute (x) — often called the search bit — grants the ability to traverse the directory and access its contents via path resolution. Without execute on a directory, a user cannot cd into it or access files within it, even if those files themselves have permissive modes.

PermissionOn Regular FileOn Directory
r (read)View file contents (cat, less, head)List directory entries (ls)
w (write)Modify or truncate file dataCreate, rename, or delete entries within directory
x (execute)Run file as a program or scriptTraverse (cd into) and resolve paths through directory

Semantic differences of rwx bits between files and directories

sudo: Policy-Based Privilege Escalation

While the rwx permission model governs normal file access, system administration routinely requires elevated privileges — installing packages, modifying firewall rules, reading protected log files, and so on. The classical approach was to log in as root via su (switch user), but this required sharing the root password and provided no granularity: once you were root, you could do anything. sudo solves both problems. It authenticates users with their own password and consults the /etc/sudoers file to determine precisely which commands that user is authorized to run as which target user (typically root), on which hosts.

sudo Execution FlowUser (alice)UID=1000runssudo apt updatecommand requestPAM AuthenticationVerify alice's passwordPolicy Check: /etc/sudoersalice ALL=(ALL) ALLIs alice allowed to run apt as root?DENIEDGRANTEDAccess DeniedLogged to /var/log/auth.logFork child processsetuid(0) → exec aptCommand runs as root (UID 0)
The sudo execution flow: a user invokes a command with sudo, which authenticates via PAM, checks the /etc/sudoers policy, and either denies access (with logging) or forks a child process that calls setuid(0) to execute the command as root. Every invocation is logged for audit purposes.

The /etc/sudoers file follows a structured syntax: user host=(runas) command. For instance, alice ALL=(ALL) /usr/bin/systemctl restart nginx permits user alice to restart nginx on any host as any user — but nothing else. This command-level granularity is what makes sudo a cornerstone of the principle of least privilege. Additionally, sudo caches credentials for a configurable timeout (typically 15 minutes), so repeated sudo invocations within that window do not re-prompt for a password. The NOPASSWD directive can eliminate the password prompt entirely for automation scenarios, though this should be used judiciously.

SECTION 6

Worked Example — Securing a Web Application Directory

Consider a scenario in which you are deploying a web application on a Linux server. The web server process runs as user www-data, and you need to configure permissions on the application directory /var/www/myapp so that the developer (user alice) can deploy code, the web server can read the files, and no other user can access the directory at all.

Configuring Permissions for a Web App Directory

  1. 1

    Step 1 — Create the Directory and Set Ownership

    First, create the directory and assign ownership. We want alice as the owner and www-data as the group so the web server can access files via group permissions.
    sudo mkdir -p /var/www/myapp followed by sudo chown alice:www-data /var/www/myapp
  2. 2

    Step 2 — Determine the Desired Permission Triplets

    The requirements translate to: User (alice) needs rwx (read to inspect, write to deploy, execute to traverse the directory). Group (www-data) needs r-x (read to serve files, execute to traverse, but no write to prevent the web process from modifying code). Others should have no permissions at all (---).
    Symbolic: rwxr-x--- → Octal: 7×100 + 5×10 + 0×1 = 0750
  3. 3

    Step 3 — Apply Permissions with chmod

    Apply the computed octal mode to the directory. The chmod command modifies the mode bits stored in the directory's inode.
    sudo chmod 0750 /var/www/myapp
  4. 4

    Step 4 — Enable setgid for Consistent Group Ownership

    To ensure that new files created within the directory automatically inherit the www-data group (instead of alice's primary group), set the setgid bit. This adds 2 to the special permissions digit, making the full mode 2750.
    sudo chmod 2750 /var/www/myapp
  5. 5

    Step 5 — Verify the Configuration

    Run ls -ld /var/www/myapp to confirm the settings. The output should show the setgid bit as an s in the group execute position.
    drwxr-s--- 2 alice www-data 4096 ... /var/www/myapp
⚠

Why Not 777?

Setting permissions to 0777 (world-readable, writable, and executable) is a common anti-pattern in tutorials. It violates least privilege by allowing any user on the system — including a compromised service account — to modify your application code. In a security audit, world-writable directories are flagged as critical findings.

SECTION 7

Strengths, Limitations, and Comparisons

The Unix DAC model and sudo have survived for over fifty years because they strike an effective balance between simplicity, performance, and security. However, no access-control mechanism is perfect, and understanding the limitations is as important as understanding the strengths — especially when designing defense-in-depth architectures for production systems.

AspectStrengthsLimitations
SimplicityThree categories × three bits = 9 bits total. Compact, fast kernel checks. Easy for administrators to reason about.Only three permission categories (user/group/others). Cannot express policies like 'alice and bob but not carol' without POSIX ACLs.
PerformancePermission checks are O(1) bitwise operations in the kernel, adding negligible overhead to system calls.Extended ACLs and MAC (SELinux) add latency and complexity when more granular controls are needed.
Auditabilitysudo logs every command invocation with timestamp, user, and target command in /var/log/auth.log or journald.DAC permission changes (chmod, chown) are not logged by default; requires auditd configuration.
Delegationsudo enables command-level delegation without sharing the root password. Users authenticate with their own credentials.Misconfigured sudoers (e.g., allowing sudo vim) can be trivially exploited to escape to a root shell.
Root BypassClear separation: unprivileged users are constrained; root can do anything. Simple mental model.Root bypasses all DAC checks, creating an all-or-nothing escalation. MAC (SELinux) can confine even root.

Strengths and limitations of the Unix DAC model and sudo

✦

KEY TAKEAWAY

The rwx/sudo model is like the foundation and load-bearing walls of a building — essential, well-understood, and present in every Linux system. But just as modern buildings add fire suppression, earthquake reinforcement, and surveillance systems, production Linux deployments layer POSIX ACLs, SELinux/AppArmor, Linux capabilities, and namespaces/cgroups on top of the DAC foundation to achieve defense in depth.

SECTION 8

Connection to Advanced Access Control Mechanisms

The traditional rwx model and sudo represent the discretionary access control (DAC) layer of Linux security. As systems have grown more complex — containers, cloud infrastructure, microservices — the security community has developed additional mechanisms that either extend or supersede DAC. Understanding how these advanced systems relate to the foundational permission model is crucial for designing secure architectures.

FeatureTraditional DAC (rwx + sudo)Advanced Mechanism
GranularityThree categories: owner, group, othersPOSIX ACLs: per-user and per-group entries on individual files. Arbitrary granularity.
Root confinementRoot (UID 0) bypasses all DAC checksSELinux/AppArmor (MAC): enforces policies that even root cannot override. Process types are confined by label.
Privilege decompositionAll-or-nothing root via setuid or sudoLinux capabilities: 40+ fine-grained privileges (e.g., CAP_NET_BIND_SERVICE) assignable per-binary or per-process.
IsolationUsers share a single kernel namespaceNamespaces & cgroups (containers): processes see isolated views of the filesystem, network, PIDs, and user IDs.
Network-levelNot applicable — file-system onlyeBPF, seccomp-BPF: filter system calls at the kernel level, restricting what a process can do regardless of UID.

Traditional DAC vs. advanced Linux security mechanisms

In practice, modern Linux security follows a defense-in-depth philosophy in which DAC is the first layer, MAC provides mandatory confinement, capabilities decompose root into manageable pieces, and container isolation limits the blast radius of a compromise. A solid understanding of rwx and sudo is the prerequisite for working with any of these advanced mechanisms — they all assume and build upon the foundational permission model. Courses in container security, cloud-native architecture, and operating system internals will explore these extensions in detail.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

A file has permissions -rw------- and is owned by user root with group root. Explain why an unprivileged user bob cannot read this file, even if bob is a member of the root group. How does the kernel's first-match evaluation work here?
Show answer
When bob attempts to read the file, the kernel first checks whether bob's UID matches the file owner's UID (root's UID = 0). Since bob's UID is not 0, the user triplet (rw-) is skipped. Next, the kernel checks whether any of bob's GIDs match the file's GID. If bob is indeed in the root group, the group triplet is applied — which is --- (no permissions). The kernel does not fall through to the others triplet once a group match is found. Therefore, bob is denied access despite being in the root group, because the group permission bits grant nothing. This illustrates the first-match-wins evaluation: the kernel uses exactly one of the three triplets, and the others are irrelevant.

Question 2: BASIC CALCULATION

Convert the symbolic permission string -rwxr--r-- into its four-digit octal representation. Then, given a umask of 0027, calculate the default permissions for a newly created regular file.
Show answer
The symbolic string -rwxr--r-- decomposes as: user = rwx = 4+2+1 = 7, group = r-- = 4+0+0 = 4, others = r-- = 4+0+0 = 4, and no special bits, so the octal mode is 0744. For the umask calculation: new files start with a base of 0666 (no execute for safety). Applying umask 0027: effective = 0666 AND NOT(0027). NOT(0027) in octal bit operations gives us 0750 as the mask. Computing 0666 AND 0750: user = 6 AND 7 = 6, group = 6 AND 5 = 4, others = 6 AND 0 = 0. The effective permissions are 0640 (rw-r-----), meaning the owner can read and write, the group can read only, and others have no access.

Question 3: INTERMEDIATE

A directory /shared has permissions drwxrwx--- owned by root:developers. User carol (a member of the developers group) creates a file inside this directory. What group will own the new file? How would adding the setgid bit change this behavior, and what is the command to set it?
Show answer
Without the setgid bit, the newly created file will be owned by carol's primary group (e.g., carol), not the developers group. This is because Linux defaults to assigning a new file's group to the creating process's effective GID. Adding the setgid bit to the directory changes this behavior: any new file or subdirectory created inside /shared will automatically inherit the directory's group (developers), ensuring consistent group ownership for collaborative work. The command is sudo chmod g+s /shared (or equivalently sudo chmod 2770 /shared). The setgid bit appears as an 's' in the group execute position when listing with ls -ld.

Question 4: APPLIED

You are hardening a production web server. The sudoers file currently contains: deploy ALL=(ALL) ALL. The deploy user only needs to restart the Nginx service and read logs in /var/log/nginx/. Write a more restrictive sudoers entry. Explain why the original entry is a security risk and how your revised entry mitigates it.
Show answer
The original entry deploy ALL=(ALL) ALL grants the deploy user unrestricted root access to every command on the system — equivalent to giving them the root password. If the deploy account is compromised (e.g., via stolen SSH keys or a CI/CD pipeline vulnerability), the attacker immediately has full root control. A restricted entry would be: deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/cat /var/log/nginx/*. This applies the principle of least privilege by limiting the deploy user to exactly two operations as root. The NOPASSWD tag is included because deployment automation typically runs non-interactively. Care must be taken with wildcard paths — the entry should be audited to ensure it cannot be exploited via path traversal (e.g., /var/log/nginx/../../etc/shadow), and the cat binary specifically does not allow shell escape, making it safer than editors like vim or less.

Question 5: CRITICAL THINKING

A security researcher discovers that a setuid-root binary /usr/local/bin/backup accepts a --output flag that writes to an arbitrary file path. Explain in detail how this could be exploited to gain persistent root access. Then propose at least three distinct mitigation strategies, comparing DAC-based, capability-based, and MAC-based approaches.
Show answer
Because the binary has the setuid bit set with root ownership, it runs with effective UID 0 regardless of who invokes it. An attacker could invoke /usr/local/bin/backup --output /etc/passwd or --output /etc/sudoers to overwrite critical system files. For example, they could craft backup output that appends a new root-equivalent user to /etc/passwd or adds an ALL=(ALL) NOPASSWD:ALL sudoers entry for their account, achieving persistent root access. Mitigation 1 (DAC): Remove the setuid bit (chmod u-s /usr/local/bin/backup) and require the backup to be run via sudo with a restrictive sudoers entry that constrains the --output argument. Mitigation 2 (Capabilities): Instead of setuid root, grant only the specific capability needed (e.g., CAP_DAC_READ_SEARCH to read files for backup) using setcap, and fix the binary to drop all other capabilities. This avoids granting full root. Mitigation 3 (MAC): Use an SELinux or AppArmor profile that confines the backup binary to writing only to designated backup directories (e.g., /var/backups), even when running as root. A MAC policy would block writes to /etc regardless of the process's UID, providing defense even against the setuid vulnerability.

SUMMARY

Lesson Summary

Summary

The Linux permission model encodes access control through a compact, efficient system of nine permission bits organized into three triplets (user, group, others), each specifying read (r = 4), write (w = 2), and execute (x = 1) access. Every file and directory carries this metadata in its inode, along with an owning UID and GID. The kernel evaluates permissions using a first-match-wins strategy, checking user, then group, then others. Special bits — setuid, setgid, and sticky — provide additional control over privilege inheritance and directory behavior.

sudo complements DAC by providing policy-controlled, audited privilege escalation through the /etc/sudoers configuration file. It enforces the principle of least privilege by granting users only the specific commands they need, authenticating with their own passwords, and logging every invocation. Together, rwx permissions and sudo form the foundational DAC layer upon which advanced mechanisms like POSIX ACLs, SELinux, Linux capabilities, and namespaces are built to achieve comprehensive defense in depth.

Varsity Tutors • Cyber Security • Linux Permissions & sudo