grayresearch / CX

Proposed RISC-V Composable Custom Extensions Specification
Apache License 2.0
66 stars 12 forks source link

secure CX multiplexing behavior upon priv mode changes #22

Open grayresearch opened 7 months ago

grayresearch commented 7 months ago

Scenario:

  1. M/U M/S/U or M/H/S/U system.
  2. U-mode app code selects a specific CX (enables CX multiplexing). Issues custom instructions to that CX.
  3. ECALL, exception, interrupt, etc. leaves U mode for a higher priv mode (say S-mode).
  4. S-mode code issues a custom instruction or accesses a custom CSR. What happens?

Consider three options:

  1. per-hart CX multiplexing: The U-mode CX selection on this hart remains in effect;
  2. per-hart U-mode-only CX multiplexing: S-mode CX is disabled: CX multiplexing is disabled when not in least priv mode. So S-mode custom instructions / CSRs always perform (that CPU's) legacy custom instructions / CSRs; and
  3. per mode, per-hart CX multiplexing: There is a per-priv-level per hart CX selection, so the S-mode custom instructions and CSRs perform CX multiplexed operations against the hart's current S-mode CX selection.

Commentary:

  1. Per-hart CX multiplexing is the current spec, and it is unacceptable. It should not (must not) be possible for U-mode code to change the behavior of e.g. S-mode code custom instructions. It is not realistic to explicitly reselect legacy custom instructions via a CSR write at every entry point from U-mode to S-mode.

  2. Per-hart U-mode-only multiplexing closes this security hole. Each instruction issued in S-mode always and only uses legacy custom instructions and CSRs. This is simple and straightforward. Unfortunately, by defintion, this denies all S-mode OS kernel use of composable extensions. This is unfortunate because there are many kernel operations (e.g. data compression) that could make great use of CXs.

  3. Extend the complement of CX multiplexing CSRs so there are disjoint CX mux CSRs for each priv level on a hart. In the scenario, the S-mode code uses the hart's current S-mode CX selection. This option closes the security hole AND enables an operating system to also use CX, at the cost of additional complexity and hardware resources.

Perhaps there are other options. Until we have a better idea or a fully elaborated option #3 design, I am inclined to update the spec with option #2. Your comments welcome.

grayresearch commented 7 months ago

An M-mode only system, e.g. austere bare metal MCUs running fully trusted firmware, should support M-mode only CX multiplexing. So option #2 should be: "CX multiplexing is only available in the least privileged implemented mode:

  1. M-ony systems: M-mode
  2. M/U, M/S/U, M/H/S/U systems: U-mode.
grayresearch commented 6 months ago

Oops, this proposal is broken / needs more work. It's unfortunate that none of you out there caught the problem! :-)

Assume we have a CX-aware OS, and when in S-mode it needs to e.g. save a CX state context. The spec (%2.6) states the OS uses standard stateful CX custom instructions: IStateContext::cf_read_status and ::cf_read_state instructions to access the state context of the current CX.

But, if we were to adopt mitigation # 2 above ("Each instruction issued in S-mode always and only uses legacy custom instructions and CSRs.") then the OS' S-mode context save code could not issue IStateContext::cf_read_status and ::cf_read_state. (Exercise: what happens if it does so anyway?)

So, back to the drawing board. I think we have

  1. Immediately on entry to S-mode from beyond, CX muxing is disabled and the hart has access to legacy custom instructions.
  2. Sometimes in S-mode the OS must be able to select a specific CX and state context and issue its custom instructions.