Access Control Lists (ACLs)
Once the hardware has verified you are in Ring 3 (User Mode), the OS Kernel must decide: Are you allowed to open this file?
This is the job of the Access Control subsystem.
1. Discretionary Access Control (DAC)
Linux and Unix systems primarily use DAC.
- “Discretionary”: The owner of the file has the discretion to set permissions.
- The Problem: If a user runs a malicious script (Trojan), that script runs with the user’s full permissions and can change permissions on all the user’s files.
The Inode & Permission Bits
Every file in a Unix filesystem is represented by an Inode. The inode stores metadata, including a 9-bit permission mask.
- User (u): The owner.
- Group (g): Users in the file’s group.
- Others (o): Everyone else.
Each scope has 3 bits: Read (4), Write (2), Execute (1).
2. Interactive: Permission Bitmask Calculator
Visualize how the kernel translates binary flags into the octal notation used by chmod.
USER (Owner)
GROUP
OTHERS
Command to Run
chmod 655 file
Symbolic
-rw-r-xr-x
3. Mandatory Access Control (MAC)
Because DAC has flaws (root can do anything, users can accidentally expose files), high-security systems use MAC (e.g., SELinux, AppArmor).
- “Mandatory”: The system defines the policy, not the user. Even root cannot override it easily.
- Labels: Files and processes have security labels.
- Policy: “The Apache process (Label:
httpd_t) can ONLY read files with Labelhttpd_content_t.” - If Apache tries to read
/etc/shadow(Label:shadow_t), the kernel blocks it, even if permissions are 777.
4. Code Example: Manipulating Permissions
System calls to change permissions.
Go
Java
package main
import (
"fmt"
"os"
)
func main() {
fileName := "secret.txt"
// Create a file
file, err := os.Create(fileName)
if err != nil {
panic(err)
}
file.Close()
// 1. Change permissions to 0600 (rw-------)
// Only the owner can read/write.
if err := os.Chmod(fileName, 0600); err != nil {
panic(err)
}
info, _ := os.Stat(fileName)
fmt.Printf("Permissions: %s\n", info.Mode())
// Output: -rw-------
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.Set;
public class PermExample {
public static void main(String[] args) throws IOException {
Path path = Paths.get("secret.txt");
if (!Files.exists(path)) Files.createFile(path);
// 1. Define permissions set using POSIX enum
Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
// No GROUP or OTHERS permissions added
// 2. Apply permissions
try {
Files.setPosixFilePermissions(path, perms);
System.out.println("Permissions set to rw-------");
} catch (UnsupportedOperationException e) {
System.out.println("POSIX permissions not supported on this OS (Windows?)");
}
}
}