diff --git a/g3doc/architecture_guide/security.md b/g3doc/architecture_guide/security.md index 9363d834c..4fb4dad11 100644 --- a/g3doc/architecture_guide/security.md +++ b/g3doc/architecture_guide/security.md @@ -142,12 +142,18 @@ filesystem attributes) and not underlying host system resources. While the sandbox virtualizes many operations for the application, we limit the sandbox's own interactions with the host to the following high-level operations: -1. Communicate with a Gofer process via a connected socket. The sandbox may - receive new file descriptors from the Gofer process, corresponding to opened - files. These files can then be read from and written to by the sandbox. +1. Establish communication with a Gofer process using a connected socket. The + Gofer process manages the container's filesystem and provides file + descriptors to the sandbox upon request. The sandbox can read from and write + to these file descriptors directly. The sandbox itself operates within an + empty mount namespace. The sandbox can be + [further tuned](../user_guide/filesystem.md#directfs) to deny all access to + the filesystem, in which case the Gofer process performs all operations on + behalf of the sandbox. 1. Make a minimal set of host system calls. The calls do not include the creation of new sockets (unless host networking mode is enabled) or opening - files. The calls include duplication and closing of file descriptors, + files (unless [directfs](../user_guide/filesystem.md#directfs) is enabled). + The calls include duplication and closing of file descriptors, synchronization, timers and signal management. 1. Read and write packets to a virtual ethernet device. This is not required if host networking is enabled (or networking is disabled). diff --git a/g3doc/user_guide/filesystem.md b/g3doc/user_guide/filesystem.md index 9b424587d..080a5bf03 100644 --- a/g3doc/user_guide/filesystem.md +++ b/g3doc/user_guide/filesystem.md @@ -54,6 +54,30 @@ filesystem is important because k8s scans the container's root filesystem from the host to enforce local ephemeral storage limits. You can also place the overlay host file in another directory using `--overlay2=root:/path/dir`. +## Directfs + +Directfs is a feature that allows the sandbox process to directly access the +container filesystem. Directfs is enabled by default in runsc and can be +disabled with `--directfs=false` flag. Directfs provides reasonable security +while maintaining good performance by avoiding gofer round trips. Irrespective +of this setting, the container filesystem is always owned by the gofer process +and the sandbox mount namespace is always empty. To learn more, see our +[blog post](https://gvisor.dev/blog/2023/06/27/directfs/) about it. + +When directfs is enabled, the gofer process donates file descriptors for all +mount points to the sandbox. The sandbox then uses file descriptor based system +calls (like `openat(2)`, `fchownat(2)`, etc) to access and operate on files +directly. The sandbox can only operate on filesystem trees exposed to it by the +gofer and cannot access the host's filesystem. There are additional security +measures like enforcing the usage of `O_NOFOLLOW` via seccomp and ensuring that +host filesystem FDs are not leaked on sandbox startup. + +When directfs is disabled, the sandbox runs with stricter seccomp filters and +fewer capabilities such that the sandbox process can not perform filesystem +operations. It communicates with the Gofer process (via RPCs) to perform +filesystem operations on its behalf. This increases security but comes with a +performance trade-off. + ## Shared root filesystem The root filesystem is where the image is extracted and is not generally diff --git a/g3doc/user_guide/install.md b/g3doc/user_guide/install.md index 6ddcf334a..63570f2a7 100644 --- a/g3doc/user_guide/install.md +++ b/g3doc/user_guide/install.md @@ -38,9 +38,9 @@ For more details about using gVisor with Docker, see production purposes. > **Note**: It is important to copy `runsc` to a location that is readable and -> executable to all users, since `runsc` executes itself as user `nobody` to -> avoid unnecessary privileges. The `/usr/local/bin` directory is a good place -> to put the `runsc` binary. +> executable to all users, since `runsc` may need to re-execute itself as an +> unprivileged user to increase security. The `/usr/local/bin` directory is a +> good place to put the `runsc` binary. ## Install from an `apt` repository