Skip to main content

plan

Function plan 

Source
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 relative user_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.