ELF Runner
<<../_v2_banner.md>>
The ELF runner is the runner responsible for launching [components][glossary.component] based on standard executable files (ELF format). It is a built-in runner and is available to all components.
Using the ELF Runner
To use the ELF runner, the component's manifest must include a program block,
containing:
- The
runnerfield with the value set to the stringelf. - The
binaryfield with the value set to a binary output name in the component's package.
Fields
Additionally, the ELF runner accepts a set of optional fields to configure the ELF component's runtime environment.
Arguments
Arguments (that is, argv in most programming languages) can be passed to a
component's process using the args field. This field accepts a vector of
strings (see the example below).
The arguments set will be passed in the same order as declared in the manifest.
Forwarding stdout and stderr streams
The stdout and stderr streams of ELF components can be routed to the
[LogSink service][logsink]. By default, the ELF runner doesn't route these
streams to any output sink. Therefore, any write to these streams, such as
printf, is lost and can be considered a no-op. If your component prints
diagnostics messages to either of these streams, you should forward the streams
to the [LogSink service][logsink].
To enable this feature, add the following to your manifest file:
After including this shard, all writes to stdout are logged as INFO messages,
and all writes to stderr are logged as WARN messages. Messages are split
by newlines and decoded as UTF-8 strings. Invalid byte sequences are converted
to the U+FFFD replacement character, which usually looks like �.
Note: There are known issues where messages from ZX_ASSERT_... in C/C++
components and Error objects returned in main in Rust components are lost.
To prevent issues where messages are lost from ZX_ASSERT_... in C/C++
components and Error objects returned from main in Rust components it is
recommended that component authors include the aforementioned shard in their
manifest.
Lifecycle
Components have a [lifecycle][lifecycle]. Components run by the ELF runner can
integrate with the lifecycle if you add a lifecycle attribute to your component
manifest. Currently stop is the only method in the Lifecycle protocol.
The program should take the handle to the Lifecycle channel and serve the
[Lifecycle protocol][lc-proto] on that channel. The component should exit after
receiving and processing the stop call.
The ELF Runner monitors the process it started for the program binary of the component. If this process exits, the ELF runner will terminate the component's execution context, which includes the component's job and all subprocesses.
Note: For a complete lifecycle example, see [//examples/components/lifecycle][lc-example].
Security
There are several privileged fields that are gated by an
[allowlist][security-allowlist]. Only components included in this allowlist
are able to use these fields. For all fields, the policy applies to the first
process in the component. The first process is the one created by ELF runner
for the binary declared in program block. All of the fields are booleans
that default to false.
Main Process Critical
The main_process_critical field may be used to mark the component's first
process as [critical to component manager's job][job-set-critical], which will
cause component manager (and all components) to be terminated if the process
exits with a non-zero code. This will force the system to trigger a hard reboot.
Ambient VMO Exec
The ambient_mark_vmo_exec field may be used to allow the component's first
process to use [zx_vmo_replace_as_executable][vmo-replace] with a
ZX_HANDLE_INVALID as the second argument rather than a valid
ZX_RSRC_KIND_VMEX.
Create Raw Processes
The create_raw_processes field may be used to allow a component to create
processes by using [zx_process_create][process-create].
Further Reading
For a detailed explanation of how processes are created, please see [Zircon program loading and dynamic linking][program-loading].
Environment Variables
Environment variables can be set for ELF components by using the environ
attribute. This field must be a vector of strings where each string contains
the variable and value delimited by an equal sign. For example, the following
sample code declares variables FAVORITE_ANIMAL and FAVORITE_COLOR to cat
and red.
{
program: {
runner: "elf",
binary: "bin/echo",
environ: [
"FAVORITE_ANIMAL=cat",
"FAVORITE_COLOR=red",
]
}
}
glossary.component capabilities/README.md#routing
lc-examplelc-protolifecycleprogram-loadingjob-set-criticaljob-set-policyprocess-createvmo-replace[fxb-72178]: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=72178
logsink /src/security/policy/component_manager_policy.json5