The handoff of execution from a boot image to an application image needs to not leak security information out of the boot image. This means that all hardware and memory data (e.g., stack image) needs to be cleaned up before the handoff. Since Zephyr is a composable system this needs a general solution that supports composability. The natural solution is to extend the system initialization feature to also support a shutdown in reverse-dependency order. This enables delaying the handoff until persistent data and hardware agents (DMA, interrupt controllers) are in a clean state expected at the handoff point.
Problem description
Currently the Zephyr system APIs do not seem to have a way to clean up the hardware and memory before handing off execution to a new image. This opens the door for leaking information from the boot image to the app image.
Proposed change
Extend the System Initialization API to also support a system shutdown in reverse dependency order. This is to be executed by the same thread that ran system initialization calls.
Detailed RFC
See Proposed change
Proposed change (Detailed)
In zephyr/include/init.h:
Extend struct init_entry with a shutdown handler: `int (shutdown)(const struct device dev);
Update existing macros using struct init_entry to initialize the shutdown field to NULL
Add *_INIT_SHUTDOWN* macros parallel to *_INIT* macros, that expose both the _init_fn, and _shutdown_fn parameters.
Add a void z_sys_shutdown_enable(void); method to enable shutdown calls once main() is returned from.
In zephyr/kernel/init.c:
Extend initialization code to call the shutdown methods in reverse dependency order, verifying the return codes indicate success.
Dependencies
This change:
increases the size of struct init_entry by at least the size of a pointer.
requires components (subsystems and drivers) to honor the shutdown request by
supporting and honoring callback un-registrations from clients
unregistering any notifications this component registered for
no longer calling other components or using OS services
failing API calls when in a shutdown state
Concerns and Unresolved Questions
None recognized
Alternatives
The following alternatives were considered:
A separate, independent shutdown handler registration: Registering the shutdown handler independent from the init handler requires describing the dependency order in multiple places, increasing the risk of mis-configuration.
Creating an assert handler registration and using this for controlled shutdown: Though an assert handler must be able to re-initialize hardware to a safe (secure?) condition at any point in time, it does not require it be left in a condition appropriate for handoff to another executable. Assert() is distinctly catastrophic.
Introduction
The handoff of execution from a boot image to an application image needs to not leak security information out of the boot image. This means that all hardware and memory data (e.g., stack image) needs to be cleaned up before the handoff. Since Zephyr is a composable system this needs a general solution that supports composability. The natural solution is to extend the system initialization feature to also support a shutdown in reverse-dependency order. This enables delaying the handoff until persistent data and hardware agents (DMA, interrupt controllers) are in a clean state expected at the handoff point.
Problem description
Currently the Zephyr system APIs do not seem to have a way to clean up the hardware and memory before handing off execution to a new image. This opens the door for leaking information from the boot image to the app image.
Proposed change
Extend the System Initialization API to also support a system shutdown in reverse dependency order. This is to be executed by the same thread that ran system initialization calls.
Detailed RFC
See Proposed change
Proposed change (Detailed)
In
zephyr/include/init.h
:struct init_entry
with a shutdown handler: `int (shutdown)(const struct device dev);struct init_entry
to initialize the shutdown field to NULL*_INIT_SHUTDOWN*
macros parallel to*_INIT*
macros, that expose both the_init_fn
, and_shutdown_fn
parameters.void z_sys_shutdown_enable(void);
method to enable shutdown calls oncemain()
is returned from.In
zephyr/kernel/init.c
:Dependencies
This change:
struct init_entry
by at least the size of a pointer.Concerns and Unresolved Questions
None recognized
Alternatives
The following alternatives were considered: