gVisor - Gofer

In the context of gVisor (Google’s open-source container runtime), a Gofer is a specialized process that acts as a file system proxy.

To understand the Gofer, you first have to understand the basic architecture of gVisor, which is built on the principle of isolation.

The Problem: The "Sentry" is Untrusted

In gVisor, the core component is the Sentry. The Sentry acts as a user-space kernel; it intercepts system calls from the application and handles them.

However, for security reasons, the Sentry is not allowed to access the host file system directly. If the Sentry were compromised by a malicious application and had direct host access, the attacker could read or delete any file on the host machine.

The Solution: The Gofer

The Gofer is a separate, standalone process that runs alongside the Sentry. Its sole job is to provide file system access to the Sentry via a secure protocol.

The Workflow:

  1. Application requests to open a file (e.g., open("/etc/passwd")).
  2. Sentry intercepts this system call.
  3. Sentry sends a request to the Gofer (via a Unix domain socket).
  4. Gofer performs the actual open() call on the host OS.
  5. Gofer passes the file descriptor back to the Sentry.

Key Characteristics of Gofer

Security (Defense in Depth)

The Gofer is heavily sandboxed using seccomp or namespaces. While the Sentry handles complex logic (networking, memory management, signals), the Gofer does only one thing: file I/O. By splitting these duties, gVisor ensures that even if the Sentry is hacked, the attacker still doesn't have the "keys" to the host filesystem—they have to go through the Gofer, which has its own strict security policies.

The Communication Protocol: From 9P to LISAFS

Historically, gVisor used a modified version of the 9P protocol (originally from the Plan 9 operating system) for the Sentry to talk to the Gofer over Unix domain sockets.

In modern gVisor, file communication uses LISAFS (Linux Sandbox File System). LISAFS is an optimized, Linux-specific protocol that uses shared-memory ring buffers for zero-copy read/write transfers and batched path traversals, greatly reducing IPC overhead.

The Modern Role with Directfs

In modern versions of runsc, gVisor introduces Directfs (enabled by default):

  • Startup Donation: Instead of the Gofer handling every individual open() or read() request in a continuous loop, the Gofer sets up the container's mount namespaces and "donates" root directory file descriptors to the Sentry at container start.
  • Direct Sentry Access: The Sentry can then perform directory-scoped operations directly via host syscalls (like openat and openat2) within strictly isolated mount namespaces and seccomp walls.
  • Fallback: For storage configurations or mounts where direct access is disabled or unsupported, the Gofer continues to serve as the active filesystem proxy over LISAFS.

Separation of Privileges

Typically, each container in a gVisor sandbox has its own Gofer process. This ensures that one container's file access is completely isolated from another container's file access.

Summary

The Gofer is gVisor's filesystem security gatekeeper. Whether proxying requests over LISAFS or bootstrapping sandboxed root directories for Directfs, it ensures that the untrusted Sentry cannot freely traverse the host filesystem, enforcing strict least-privilege isolation.

Loading...