Expand description
execve handling at the ptrace stop.
The kernel resolves the program path and its PT_INTERP on the host, so
both must be rewritten before the syscall proceeds:
- the program path is translated, and
#!scripts are expanded into interpreter plus argument, repeatedly, until an ELF is reached; - a dynamically linked ELF is not executed directly. One of the host’s
machine is exec’d through the loader the exec shim installs (see
shim::loader_path), with the program’s guest path as an argument: the loader opens the program and the interpreter itsPT_INTERPnames throughopenat, which the handlers translate, maps them where the kernel would and jumps to the interpreter, which then runs as if the kernel had loaded the program. Any other, a 32-bit one or one where the loader cannot run, is re-targeted at the host copy of its dynamic loader, with the program’s guest path as the dynamic loader’s argument; - the new argv is written on the tracee’s stack and the registers point
at it.
envpis untouched.
Set PROOT_EXEC_DEBUG=1 to print every rewritten exec on stderr.
Without ptrace the same plan is carried out by a trampoline inside the
tracee instead of a register rewrite, see shim. An exec of proot or
bwrap themselves is a nested launch, planned by nested and carried out
by the trampoline in both modes.
Known gaps: at the kernel level /proc/<pid>/exe names the loader, or
the dynamic loader; the supervisor answers readlink on /proc/self/exe
from the record kept here. A program the loader started reads the path
its caller named as AT_EXECFN; one started by its dynamic loader reads
the alias it was exec’d through.
Both ABIs are handled: argv is read and written with the caller’s pointer
width (the kernel interprets execve arguments in the caller’s ABI), and a
32-bit ELF is re-targeted at its own 32-bit loader.
Modules§
- elf
- Minimal ELF reader, 32- and 64-bit: enough to find
PT_INTERP. - nested
- Nested proot and bwrap: a view of their own instead of a supervisor of their own.
- shebang
#!line parsing with the kernel’s rules.- shim
- The exec trampoline: a static binary installed in the alias directory as
e, and the record files that tell it what to run.
Structs§
- Exec
Plan - What the kernel should load in place of what the tracee asked for.
- Trampoline
- What the trampoline does inside the tracee before exec’ing the plan.
Constants§
- HOST_
MACHINE 🔒 e_machineof the host’s programs, the ones the loader maps.- LOADER_
ARGS - Number of entries the loader takes before the program’s own argument vector: its alias, the
program and the path to report as
AT_EXECFN. - MAX_
ARGV 🔒 - Upper bound on argv entries read from the tracee.
- MAX_
SHEBANG_ 🔒DEPTH - Maximum nesting of
#!interpreters (the kernel allows 4).
Statics§
Functions§
- alias_
dir - Directory holding the loader aliases, private to this supervisor.
- alias_
subdir 🔒 - The directory of the aliases of one target, named by a hash of its path.
- debug_
exec - Prints the rewritten exec when
PROOT_EXEC_DEBUGis set. - exec_
name 🔒 - The name the kernel would give a process exec’d as
user_path: the last component of that path, or ofguest_progwhen the path is empty (execveatof a descriptor) or ends in a slash. - finish_
pending - Completes a pending exec at the trampoline’s exec of the real target: records the program and moves the process into its new view, if any.
- handle_
execve - Rewrites an
execve/execveatso the kernel loads host-side files only. - is_
loader_ alias - Whether
pathis an alias of the loader, theargv[0]of a program it loaded. - loader_
alias 🔒 - A symlink to
host_interpwhose basename is the program’s, forexecve. - loader_
supports_ 🔒argv0 - Whether the loader at
host_interpunderstands--argv0. - pending_
of - What to remember about a process between its exec of the trampoline and the trampoline’s exec of the real target.
- plan
- Works out what to exec for a program the tracee named.
- plan_in
planin a given view.- push_
argv 🔒 - Writes a path and an argv array onto the tracee’s stack.
- read_
argv - Reads the tracee’s argument vector.
- set_
alias_ dir - Fixes the alias directory before anything used it (the shim installer).