diff mbox series

[v3,2/4] arm64: smccc: clear the Xn registers after SMC calls

Message ID 20220801172053.20163-3-abdellatif.elkhlifi@arm.com
State Superseded
Delegated to: Tom Rini
Headers show
Series introduce Arm FF-A support | expand

Commit Message

Abdellatif El Khlifi Aug. 1, 2022, 5:20 p.m. UTC
set to zero the x0-x17 registers

As per the SMCCC v1.2 spec, unused result and scratch registers can leak
information after an SMC call. We can mitigate against this risk by
returning zero in each register.

Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
---
 arch/arm/cpu/armv8/smccc-call.S | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Jens Wiklander Aug. 16, 2022, 11:48 a.m. UTC | #1
On Mon, Aug 1, 2022 at 7:21 PM Abdellatif El Khlifi
<abdellatif.elkhlifi@arm.com> wrote:
>
> set to zero the x0-x17 registers
>
> As per the SMCCC v1.2 spec, unused result and scratch registers can leak
> information after an SMC call. We can mitigate against this risk by
> returning zero in each register.
>
> Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> Cc: Jens Wiklander <jens.wiklander@linaro.org>
> ---
>  arch/arm/cpu/armv8/smccc-call.S | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
> index ec6f299bc9..8ac3e461e4 100644
> --- a/arch/arm/cpu/armv8/smccc-call.S
> +++ b/arch/arm/cpu/armv8/smccc-call.S
> @@ -84,6 +84,26 @@ ENDPROC(__arm_smccc_hvc)
>         stp     x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS]
>         stp     x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS]
>
> +       /* x0-x17 registers can leak information after an SMC or HVC call. Let's clear them */
> +       mov     x0, xzr
> +       mov     x1, xzr
> +       mov     x2, xzr
> +       mov     x3, xzr
> +       mov     x4, xzr
> +       mov     x5, xzr
> +       mov     x6, xzr
> +       mov     x7, xzr
> +       mov     x8, xzr
> +       mov     x9, xzr
> +       mov     x10, xzr
> +       mov     x11, xzr
> +       mov     x12, xzr
> +       mov     x13, xzr
> +       mov     x14, xzr
> +       mov     x15, xzr
> +       mov     x16, xzr
> +       mov     x17, xzr
> +

Is this information leakage worse than the information leakage from an
ordinary C function?
My point is, is this needed?

Thanks,
Jens

>         /* Restore original x19 */
>         ldp     xzr, x19, [sp], #16
>         ret
> --
> 2.17.1
>
Abdellatif El Khlifi Sept. 26, 2022, 11:33 a.m. UTC | #2
On Tue, Aug 16, 2022 at 01:48:31PM +0200, Jens Wiklander wrote:
> On Mon, Aug 1, 2022 at 7:21 PM Abdellatif El Khlifi
> <abdellatif.elkhlifi@arm.com> wrote:
> >
> > set to zero the x0-x17 registers
> >
> > As per the SMCCC v1.2 spec, unused result and scratch registers can leak
> > information after an SMC call. We can mitigate against this risk by
> > returning zero in each register.
> >
> > Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
> > Cc: Tom Rini <trini@konsulko.com>
> > Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> > Cc: Jens Wiklander <jens.wiklander@linaro.org>
> > ---
> >  arch/arm/cpu/armv8/smccc-call.S | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
> > index ec6f299bc9..8ac3e461e4 100644
> > --- a/arch/arm/cpu/armv8/smccc-call.S
> > +++ b/arch/arm/cpu/armv8/smccc-call.S
> > @@ -84,6 +84,26 @@ ENDPROC(__arm_smccc_hvc)
> >         stp     x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS]
> >         stp     x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS]
> >
> > +       /* x0-x17 registers can leak information after an SMC or HVC call. Let's clear them */
> > +       mov     x0, xzr
> > +       mov     x1, xzr
> > +       mov     x2, xzr
> > +       mov     x3, xzr
> > +       mov     x4, xzr
> > +       mov     x5, xzr
> > +       mov     x6, xzr
> > +       mov     x7, xzr
> > +       mov     x8, xzr
> > +       mov     x9, xzr
> > +       mov     x10, xzr
> > +       mov     x11, xzr
> > +       mov     x12, xzr
> > +       mov     x13, xzr
> > +       mov     x14, xzr
> > +       mov     x15, xzr
> > +       mov     x16, xzr
> > +       mov     x17, xzr
> > +
> 
> Is this information leakage worse than the information leakage from an
> ordinary C function?
> My point is, is this needed?

The leakage we are referring to is data leakage across exception levels.
The intent is to prevent lower exception levels (EL1/EL0) to read the 
data exchanged at EL2.

The linux kernel clears the general purpose registers before switching 
to EL0. As far as I know u-boot doesn't. 

So, the code above makes sure the registers are cleared.
An improved version of this has been releases in this 
patch: https://lore.kernel.org/all/20220926101723.9965-3-abdellatif.elkhlifi@arm.com/

> 
> Thanks,
> Jens
> 
> >         /* Restore original x19 */
> >         ldp     xzr, x19, [sp], #16
> >         ret
> > --
> > 2.17.1
> >
diff mbox series

Patch

diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
index ec6f299bc9..8ac3e461e4 100644
--- a/arch/arm/cpu/armv8/smccc-call.S
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -84,6 +84,26 @@  ENDPROC(__arm_smccc_hvc)
 	stp	x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS]
 	stp	x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS]
 
+	/* x0-x17 registers can leak information after an SMC or HVC call. Let's clear them */
+	mov	x0, xzr
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+	mov	x4, xzr
+	mov	x5, xzr
+	mov	x6, xzr
+	mov	x7, xzr
+	mov	x8, xzr
+	mov	x9, xzr
+	mov	x10, xzr
+	mov	x11, xzr
+	mov	x12, xzr
+	mov	x13, xzr
+	mov	x14, xzr
+	mov	x15, xzr
+	mov	x16, xzr
+	mov	x17, xzr
+
 	/* Restore original x19 */
 	ldp     xzr, x19, [sp], #16
 	ret