Vendor: containerd Project
Vendor URL: https://containerd.io/
Versions affected: 1.3.x, 1.2.x, 1.4.x, others likely
Systems Affected: Linux
Author: Jeff Dileo
CVE Identifier: CVE-2020-15257
Advisory URL: https://github.com/containerd/containerd/security/advisories/GHSA-36xw-fx78-c5r4
Risk: High (full root container escape for a common container configuration)

containerd is a container runtime underpinning Docker and common Kubernetes
configurations. It handles abstractions related to containerization and
provides APIs to manage container lifecycles. containerd-shim is a binary
spawned by containerd that serves as the parent of a container and which
implements container lifecycle and reconnection logic that it exposes to
containerd through the containerd shim API. This API is exposed over an
abstract namespace Unix domain socket that is accessible from the root network
namespace. Due to this, non-user namespaced containers with host networking
can access this API and cause containerd-shim to perform dangerous actions and
spin up arbitrarily privileged containers, enabling container escapes and
escalation to full root privileges on the host.

  • containerd/containerd
    • runtime/v1/shim/client/client.go: WithStart(), newCommand()
    • cmd/containerd-shim/main_unix.go: serve()
    • cmd/containerd-shim/shim_linux.go: newServer()
  • containerd/ttrpc (via vendor/github.com/containerd/ttrpc/unixcreds_linux.go)
    • unixcreds_linux.go: UnixSocketRequireSameUser()

An attacker that is able to run or compromise a host network container running
as UID 0 can escape the container, escalate privileges, and compromise the host.

containerd is a core container runtime, which manages runc-based containers,
and is used by Docker (from which it was spun out of) and Kubernetes, either
through Docker or directly through the containerd CRI shim. Generally,
containerd exists as a long-running service daemon that exposes gRPC APIs
(e.g. those for containers and tasks) for container lifecycle management operations (e.g. container
execution and supervision, image handling, etc.). To implement its APIs,
containerd does not directly parent the containers that it creates and
oversees on behalf of its clients. Instead, containerd spawns containerd-shim
processes that manage the lifecycle of each container. containerd-shim stays
alive for the course of the container’s life to manage it and directly invokes
the runc binary to directly spawn and run the container itself.

To serve its own gRPC (actually ttrpc, an embedded gRPC implementation and
wire protocol) APIs (e.g. v1 and v2), containerd-shim listens on an abstract Unix
domain socket. These are Linux-specific Unix domain sockets that use
length-prefixed keys that begin with a null byte and may contain arbitrary
binary sequences. These containerd-shim sockets take different forms across
different containerd versions; however, a common behavior is that they embed a
trailing null byte in the abstract Unix domain socket sun_path key, which
prevents a number of common Unix tools (e.g. socat) from connecting to it.

  • @/containerd-shim///shim.sock