Consider using discourse/ruby-landlock to narrow file permissions
- Dominant language
- Ruby
- Stars
- 23
- Forks
- 0
- Avg merge
- 11h 43m
- Merged PRs (30d)
- 27
Description
A worker runs as the same user as the supervisor, and that user must be able to write the socket directory. So a worker that achieves code execution can unlink `work.sock` and bind its own, and every later request arrives at its listener with the caller's descriptors attached.
`Supervisor#verify_sockets` records each socket's inode and stops the cell when it changes. That is detection, not prevention: the attacker still serves whatever arrives before the next check.
Every prevention available to an unprivileged container was ruled out, and the reasons are in that method's comment. A tighter directory mode is undone by the owner, the sticky bit grants the owner what it withholds from others, the immutable flag needs `CAP_LINUX_IMMUTABLE`, a uid per worker needs `CAP_SETUID`, and an abstract-namespace socket cannot be reached across `network: none`.
Landlock is the one that was not ruled out. It lets an unprivileged process apply an irreversible filesystem restriction to itself and its children, with no capability. A worker would give up write and unlink access to the socket directory immediately after the fork, before it touches an untrusted byte. Being irreversible is the property that matters here: there is nothing for the attacker to undo.
[discourse/ruby-landlock](https://github.com/discourse/ruby-landlock) is a binding to evaluate.
Worth considering at the same time, since a ruleset costs the same whether it names one directory or several:
- the slot workspace, where a worker can read a concurrent request's staged files
- `/hotcell`, which holds `config.rb` and the operations the supervisor loads at boot
Open questions: the kernel version floor, whether the runtime's seccomp profile permits the Landlock syscalls, what a cell does when they are unavailable, and whether a restriction that tight breaks a toolchain that writes where we did not expect.
Raised by the pre-release security review.
Contributor guide
Research direction
Start with Supervisor#verify_sockets and its comment, then evaluate the discourse/ruby-landlock binding against the worker lifecycle described in the issue. Check the kernel version floor, seccomp permissions, unavailable-Landlock behavior, and toolchain filesystem needs. Done means a documented feasibility decision and a defined restriction and fallback behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, ruby
- Domain
- operating-systems, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100