Skip to content

Security: Clean disable of boot image and hardware before handoff to app image #44564

Open
@gregshue

Description

@gregshue

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 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
    • 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:

  1. 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.
  2. 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

Assignees

Labels

RFCRequest For Comments: want input from the communityarea: SecuritySecurity

Type

Projects

Status

No status

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions