pub fn plan(
ctx: &Ctx,
pid: u32,
dirfd: i32,
user_path: &[u8],
argv: Vec<Vec<u8>>,
deref_final: bool,
env: EnvSource,
) -> Result<ExecPlan, i32>Expand description
Works out what to exec for a program the tracee named.
#! scripts are expanded into interpreter plus argument, repeatedly,
until an ELF is reached. A dynamically linked ELF of the host’s machine
is re-targeted at the shim’s loader, given its alias, the program’s
canonical guest path, the path to report as AT_EXECFN (the one the
caller named) and then the caller’s argument vector whole; the loader
maps the program where the kernel would, below the break, far from the
libraries and from what the program maps later. The dynamic loader then
takes $ORIGIN from /proc/self/exe, answered with the canonical path.
Any other dynamically linked ELF is re-targeted at the host copy of its
dynamic loader with the program’s guest path as the dynamic loader’s
argument. The dynamic loader takes the program’s $ORIGIN from the
path it is given, where the kernel would take it from the resolved
executable, so one that accepts --argv0 gets the canonical path and the
name as typed separately; one without it uses the path as argv[0], on
which multi-call binaries (busybox) dispatch, so it gets the name as
typed unless that name is dirfd-relative and meaningless after the
rewrite.
Either loader is reached through an alias named as the tracee named the
program, which is where the kernel takes comm from, so a script keeps
its own name rather than its interpreter’s. In the guest-stub restricted
mode the program itself is the plan: the trampoline loads it and its
interpreter the way the kernel would.
An exec of proot or bwrap is a nested launch and is planned by
nested::plan in the view it describes.
§Arguments
ctx- Shared supervisor state.pid- Tracee thread id.dirfd- Base of a relativeuser_path.user_path- Program path as the tracee passed it.argv- The tracee’s argument vector (empty when it passed NULL).deref_final- Follow a symlink in the final component of the program path.env- The tracee’s environment, read only for a nested launch.
§Errors
ELOOP for too many nested #!, otherwise the errno of translating a
path. A missing or unreadable program is not an error here: the plan
names its translated path and understood is false.