judge-server
judge-server copied to clipboard
Landlock support
Linux 5.13 introduced a new security subsystem, Landlock, that we can make use of in cptbox for filesystem sandboxing.
Currently, cptbox in the standard configuration makes use of seccomp to whitelist syscalls, and trap into ptrace for syscalls that need either sanitization or unconditional failure with an error code (e.g., socket). The latter can already be done by seccomp; we just don't do so currently out of laziness. Landlock would allow us to drop ptrace entirely, and let the kernel do more of the heavy lifting. A ptrace-less implementation would also remove the need for multiprocessed programs to take a performance hit.
A non-exhaustive checklist of things that need to happen:
- [x] Filesystem filters need to be rewritten to not use regex. Landlock provides "allow file read" and "allow (recursive) directory read" primitives; these are sufficient for our purposes (and can be converted to regex for the ptrace + seccomp backend). A first step would be to get this working with the ptrace + seccomp backend, before starting work on the Landlock bits.
BASE_FILESYSTEM is currently defined as
BASE_FILESYSTEM = [
'/dev/(?:null|tty|zero|u?random)$',
'/usr/(?!home)',
'/lib(?:32|64)?/',
'/opt/',
'/etc$',
'/etc/(?:localtime|timezone)$',
'/usr$',
'/tmp$',
'/$',
]
A Landlock-friendly version could look something like
BASE_FILESYSTEM = Root((
Dir("usr", (
Self(),
*(Dir(d, (All(),)) for d in os.listdir("/usr") if d != "home")
)),
Dir("tmp", (Self(),)),
Dir("etc", (
Self(),
File("localtime"),
File("timezone"),
)),
Dir("dev", (
File("null"),
File("tty"),
File("zero"),
File("urandom"),
File("random"),
)),
Dir("lib", (All(),))
Dir("lib32", (All(),))
Dir("lib64", (All(),))
Dir("opt", (All(),))
))
These objects should support composition:
a = Root((
Dir("etc", (
File("nsswitch.conf")))))
b = Root((
Dir("etc", (
File("passwd")))))
a + b
should be equivalent to
Root((
Dir("etc", (
File("nsswitch.conf"),
File("passwd")))))
- [x] Drop support
DMOJ_USE_SECCOMP=no, and clean up any fallback paths. We do not want to maintain all three {ptrace only, ptrace + seccomp, seccomp + landlock} backends, given we'd only be running the latter in production. - [ ] Add a
DMOJ_USE_LANDLOCKtoggle. We'd probably want to default this tonofor now. - [x] https://github.com/DMOJ/judge-server/issues/793