From 2aae6cee3c1ed10004c10efe694e8cdb2ad8e62b Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Tue, 21 May 2024 17:05:58 +0100 Subject: [PATCH] Remove the exciting jump instruction from boot.S This cjalr cra is in some code that is first hit after a cjal and so the cjalr cra returns. The caller then discards the value written back to cra as the link operation in the jump-and-link instruction. It is then used as a call, with cra initialised to a jump address. This was done as a code-size optimisation, but there's actually no need to zero the registers at the start. The code that runs with the (possibly uninitialised) values in registers (most implementations will zero in boot ROM or hardware anyway) all runs with access to the primordial capabilities and so there is no way that this can possibly leak information. The first untrusted code runs after the *second* pass through this block. Simply removing this should shave 10 bytes off the loader without affecting security. More importantly, this is the *only* place where we abuse cjalr in this way. This abuse is incompatible with separating sentries into forward and backward control-flow arcs (see Microsoft/CHERIoT-Sail#54), which has a much bigger impact on security. --- sdk/core/loader/boot.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sdk/core/loader/boot.S b/sdk/core/loader/boot.S index 60da6f0a..ae915cba 100644 --- a/sdk/core/loader/boot.S +++ b/sdk/core/loader/boot.S @@ -13,10 +13,10 @@ .p2align 2 .type start,@function start: - cjal .Lregs_clear - // The common register clearing function will not zero these registers. - zeroRegisters ra, sp, gp, a0 - // At this point all registers are cleared. + // Most hardware will have zeroed all general-purposes registers at this + // point, but any code between here and the call into the scheduler has + // access to the root capabilities and so we are not concerned about + // information / capability leakage. #if __has_include() # include #endif @@ -142,7 +142,6 @@ start: addi s1, s1, -16 csetbounds ca0, csp, s1 -.Lregs_clear: // a0 is used to pass arguments to the scheduler entry. zeroAllRegistersExcept ra, sp, gp, a0 cjalr cra