Expand description
How the supervisor gets the right to reach its tracees.
Both modes need the kernel’s ptrace access check to pass towards every
tracee: the tracer for PTRACE_SEIZE, the no-ptrace mode for
process_vm_readv and /proc/<pid>/mem. Yama’s ptrace_scope of 2
grants that only to a holder of CAP_SYS_PTRACE in the tracee’s user
namespace, so where the plain check is refused the first tracee is moved
into a user namespace of its own, which the supervisor owns from outside
and therefore holds every capability in. The namespace maps the caller’s
own uid and gid onto themselves and nothing else.
Where neither ptrace nor a user namespace works (the common Kubernetes
case), the guest-stub restricted mode (see guest_stub) needs no access
to a guest’s memory at all: a stub inside each guest process moves the
memory a served syscall uses into a mailbox both sides map. It is the
fallback on x86_64 and aarch64, ruled out by PROOT_GUEST_STUB=0.
The choice is made empirically: a child is forked and the supervisor
tries the accesses it will need on it, first as it is, then inside a user
namespace. A host where neither works (Yama 3, an LSM policy, a profile
that also filters unshare) falls back to the guest stub, or where that
is unavailable or ruled out gets an error instead of a guest that hangs.
Structs§
- Access
- What the probe settled on.
- Trial 🔒
- Outcome of one probe child.
- UserNs
- Everything the first tracee needs to enter its user namespace, prepared
before
forkso the child does not allocate.
Statics§
- MARKER 🔒
- A value the probe reads back from the child’s copy of the supervisor’s memory, proving the read reached it.
Functions§
- probe
- Decides how the supervisor reaches its tracees.
- read_
marker 🔒 - Reads
MARKERfrom the child the way the notification handlers will:process_vm_readv, or/proc/<pid>/memwhere that is filtered. - refusal 🔒
- Builds the message for a host where no plan reaches a child.
- seize 🔒
- Seizes the probe child; it is killed right after, which ends the trace.
- trial 🔒
- Forks a child that waits, tries the supervisor’s accesses on it, and kills it.
- write_
file 🔒 - Writes
textto the file atpath. Allocation free.