Description
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
:
- 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 oncemain()
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
- completing or aborting work-in-progress
- cancelling outstanding asynchronous operations (including DMAs, interrupt controllers, timers, crypto algorithm states)
- 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.
Metadata
Metadata
Type
Projects
Status
Status