Landlock-Ing Linux
Source: Hacker News
Landlock‑Ing Linux
Landlock: What Is It?
Landlock is a Linux API that lets applications explicitly declare which resources they are allowed to access. Its philosophy is similar to OpenBSD’s unveil() and (less so) pledge(): programs can make a contract with the kernel stating, “I only need these files or resources — deny me everything else if I’m compromised.”
It provides a simple, developer‑friendly way to add defense‑in‑depth to applications. Compared to traditional Linux security mechanisms, Landlock is vastly easier to understand and integrate.
How Does It Work?
Landlock is a Linux Security Module (LSM) available since Linux 5.13. Unlike MAC frameworks such as SELinux or AppArmor, Landlock applies transient restrictions:
- Policies are created at runtime.
- They are enforced on the current thread and its future descendants.
- They disappear when the process exits.
You don’t tag files with labels or extended attributes. Instead, applications create policies dynamically.
A Landlock policy consists of two pieces:
- Handled accesses – the categories of operations you want to restrict (e.g., filesystem read/write).
- Access grants – an explicit allow‑list of which objects are permitted for those operations.
Example policy
- Handle all filesystem reads/writes and network binds.
- Grants:
- read‑only access to
/home/user - read/write access to
/tmp - permission to bind to port
2222
- read‑only access to
The application then calls landlock_restrict_self() to enter the restricted domain. From that point on, the thread’s child threads and child processes are permanently constrained; restrictions cannot be revoked.
- Layering – up to 16 layers. A child layer may further reduce access but cannot re‑introduce permissions removed by its parent.
- Unprivileged – any application can sandbox itself.
- ABI versioning – programs can apply best‑effort sandboxing even on older kernels.
- Stackable LSM – can be combined with SELinux or AppArmor.
Why Should You Use It?
Landlock shines when an application has a predictable set of files or directories it needs. Example: a web server could restrict itself to /var/www/html and /tmp.
- No administrator involvement or system‑wide configuration is required.
- Policies are embedded directly in application code.
- No special privileges are needed, making adoption straightforward.
- Language bindings exist for Rust, Go, Haskell, etc. (no official C library yet).
Rust example
use landlock::{
ABI, AccessFs, Ruleset, RulesetAttr, RulesetCreatedAttr, RulesetStatus, RulesetError,
path_beneath_rules,
};
fn restrict_thread() -> Result<(), RulesetError> {
let abi = ABI::V1;
let status = Ruleset::default()
.handle_access(AccessFs::from_all(abi))?
.create()?
// Read‑only access to /usr, /etc and /dev.
.add_rules(path_beneath_rules(&["/usr", "/etc", "/dev"], AccessFs::from_read(abi)))?
// Read‑write access to /home and /tmp.
.add_rules(path_beneath_rules(&["/home", "/tmp"], AccessFs::from_all(abi)))?
.restrict_self()?;
match status.ruleset {
RulesetStatus::FullyEnforced => println!("Fully sandboxed."),
RulesetStatus::PartiallyEnforced => println!("Partially sandboxed."),
RulesetStatus::NotEnforced => println!("Not sandboxed! Please update your kernel."),
}
Ok(())
}
The State of Linux Sandboxing: Why This Matters
Linux adoption is growing, and so is malware targeting desktop users. While Linux has historically been relatively safe, that is due more to market share and technical barriers than inherent security.
Typical risks on major distributions:
- Users can execute untrusted binaries without warnings.
- Shell scripts can be piped from the internet and run blindly.
- Password‑less
sudois common, granting root on demand.
Unprivileged applications can usually:
- Read
$HOMEfiles (~/.ssh,~/.bashrc, browser cookies, …). - Modify environment variables and
$PATH. - Create systemd user services.
- (On X11) log keystrokes and read input devices.
- Bind to arbitrary network ports.
Existing sandboxing approaches
| Approach | Pros | Cons |
|---|---|---|
| Containerization (Docker, Podman) | Strong isolation for services | Not suited for desktop apps; home‑dir access is clunky; --privileged breaks isolation |
| Flatpak / Snap | Good for graphical apps | Often require overly broad permissions; less suitable for CLI tools |
| Firejail | Per‑application profiles | Needs explicit invocation or wrapper scripts |
| seccomp | Fine‑grained syscall filtering | Tedious, error‑prone; blacklists fragile; TOCTOU hazards |
| SELinux | Extremely powerful | Complex, requires admin policies, often disabled on desktops |
| AppArmor | Easier than SELinux | Still admin‑defined, system‑wide, sometimes disabled |
| Landlock | Unprivileged, application‑centric, easy to integrate, deny‑by‑default, supported since 5.13, backward/forward compatible | Still maturing; no official C library yet |
Landlock fills a major gap: a simple, self‑contained, unprivileged sandboxing tool.
What Landlock Could Bring to the Table
- System daemons with elevated privileges could be restricted to the files they truly need.
- Desktop applications (PDF readers, image viewers, browsers, word processors) could be limited to the files they opened.
- Servers (FTP, HTTP) could be bound only to required resources; even if compromised, an attacker couldn’t read arbitrary files.
- A future supervisor mode could enable Android‑style permission prompts, allowing users to grant or deny access interactively.
- Coupled with a GUI and a permission‑grant manager, Landlock could dramatically improve desktop security.
Ongoing Work in Landlock
- Supervise Mode – lets a userspace “supervisor” interactively allow or deny access (similar to Android permission prompts).
- Socket Restrictions – fine‑grained control over socket types and ports.
- LANDLOCK_RESTRICT_SELF_TSYNC – upcoming kernel feature for synchronized restriction across threads.
These developments aim to make Landlock an even more versatile and user‑friendly sandboxing solution.