Running with fully `mlock`ed memory
- Dominant language
- Go
- Stars
- 19.3k
- Forks
- 2k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 264
Description
### Description
Add a mode whereby all gVisor memory pages, including those of the sandboxed application, are `mlock`ed (i.e. they cannot be paged out to swap).
This is useful for situations where it is desirable to leave no trace of the sandboxed workload on the host system.
### Is this feature related to a specific bug?
See [discussion here](https://github.com/freedomofpress/dangerzone/issues/633). Dangerzone is a project from the Freedom of the Press Foundation which handles potentially-dangerous, potentially-sensitive/confidential documents. As part of its document processing, it needs to run several applications and libraries (LibreOffice, PyMuPDF, etc.) which don't all support such a "traceless" mode. However, these applications run within gVisor, with all data only written to `tmpfs` mounts (which are backed by gVisor memory). Therefore, if we can `mlock` all gVisor memory pages, we can systematically guarantee that no traces of the document will be left on the host system.
### Do you have a specific solution in mind?
Per @nixprime (thanks!), there are two possible solutions:
- Use `mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT)` during boot. This works naturally for the KVM platform, but for Systrap we need to also call this for subprocesses, as it is not inherited across `fork()`. Because of the platform-specificity of this solution, this also requires adding some platform method to indicate whether it supports this feature. This solution also requires some hook in `pgalloc`'s `mlockDisabled` to always be `false` in such a mode, such that `tryPopulateMlock` (which calls `munlock`) is skipped.
- Add a `pgalloc.MemoryFile.MlockAllocated`, which causes `MemoryFile.Allocate` to ignore `AllocOpts.Mode` and always `mlock` the allocated range, and causes `MemoryFile.runReclaim` to `munlock` the range. Need to confirm that `fallocate(..., FALLOC_FL_PUNCH_HOLE, ...)` works on `mlock`'d memory (so that `MemoryFile.decommitFile` still works), and still need to call `mlock(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT)` during boot if we want to `mlock` the Go heap/stack data (which could contain sensitive things like filenames, env variables etc.)
Contributor guide
Assessment
This issue has not been assessed yet.