blob: eacdc7bcd1a198675c51ff51f9239ff996ac8497 [file] [log] [blame]
Joel Hutton9e605632019-02-25 15:18:56 +00001+----------------+-------------------------------------------------------------+
2| Title | Not saving x0 to x3 registers can leak information from one |
3| | Normal World SMC client to another |
4+================+=============================================================+
Paul Beesley75017f22019-03-05 17:10:07 +00005| CVE ID | `CVE-2018-19440`_ |
Joel Hutton9e605632019-02-25 15:18:56 +00006+----------------+-------------------------------------------------------------+
7| Date | 27 Nov 2018 |
8+----------------+-------------------------------------------------------------+
9| Versions | All |
10| Affected | |
11+----------------+-------------------------------------------------------------+
12| Configurations | Multiple normal world SMC clients calling into AArch64 BL31 |
13| Affected | |
14+----------------+-------------------------------------------------------------+
15| Impact | Leakage of SMC return values from one normal world SMC |
16| | client to another |
17+----------------+-------------------------------------------------------------+
18| Fix Version | `Pull Request #1710`_ |
19+----------------+-------------------------------------------------------------+
20| Credit | Secmation |
21+----------------+-------------------------------------------------------------+
22
23When taking an exception to EL3, BL31 saves the CPU context. The aim is to
24restore it before returning into the lower exception level software that called
25into the firmware. However, for an SMC exception, the general purpose registers
26``x0`` to ``x3`` are not part of the CPU context saved on the stack.
27
28As per the `SMC Calling Convention`_, up to 4 values may be returned to the
29caller in registers ``x0`` to ``x3``. In TF-A, these return values are written
30into the CPU context, typically using one of the ``SMC_RETx()`` macros provided
31in the ``include/lib/aarch64/smccc_helpers.h`` header file.
32
33Before returning to the caller, the ``restore_gp_registers()`` function is
34called. It restores the values of all general purpose registers taken from the
35CPU context stored on the stack. This includes registers ``x0`` to ``x3``, as
36can be seen in the ``lib/el3_runtime/aarch64/context.S`` file at line 339
37(referring to the version of the code as of `commit c385955`_):
38
39.. code:: c
40
41 /*
42 * This function restores all general purpose registers except x30 from the
43 * CPU context. x30 register must be explicitly restored by the caller.
44 */
45 func restore_gp_registers
46 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
47 ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
48
49In the case of an SMC handler that does not use all 4 return values, the
50remaining ones are left unchanged in the CPU context. As a result,
51``restore_gp_registers()`` restores the stale values saved by a previous SMC
52request (or asynchronous exception to EL3) that used these return values.
53
54In the presence of multiple normal world SMC clients, this behaviour might leak
55some of the return values from one client to another. For example, if a victim
56client first sends an SMC that returns 4 values, a malicious client may then
57send a second SMC expecting no return values (for example, a
58``SDEI_EVENT_COMPLETE`` SMC) to get the 4 return values of the victim client.
59
60In general, the responsibility for mitigating threats due to the presence of
61multiple normal world SMC clients lies with EL2 software. When present, EL2
62software must trap SMC calls from EL1 software to ensure secure behaviour.
63
64For this reason, TF-A does not save ``x0`` to ``x3`` in the CPU context on an
65SMC synchronous exception. It has behaved this way since the first version.
66
67We can confirm that at least upstream KVM-based systems mitigate this threat,
68and are therefore unaffected by this issue. Other EL2 software should be audited
69to assess the impact of this threat.
70
71EL2 software might find mitigating this threat somewhat onerous, because for all
72SMCs it would need to be aware of which return registers contain valid data, so
73it can sanitise any unused return registers. On the other hand, mitigating this
74in EL3 is relatively easy and cheap. Therefore, TF-A will now ensure that no
75information is leaked through registers ``x0`` to ``x3``, by preserving the
76register state over the call.
77
78Note that AArch32 TF-A is not affected by this issue. The SMC handling code in
79``SP_MIN`` already saves all general purpose registers - including ``r0`` to
80``r3``, as can be seen in the ``include/lib/aarch32/smccc_macros.S`` file at
81line 19 (referring to the version of the code as of `commit c385955`_):
82
83.. code:: c
84
85 /*
86 * Macro to save the General purpose registers (r0 - r12), the banked
87 * spsr, lr, sp registers and the `scr` register to the SMC context on entry
88 * due a SMC call. The `lr` of the current mode (monitor) is expected to be
89 * already saved. The `sp` must point to the `smc_ctx_t` to save to.
90 * Additionally, also save the 'pmcr' register as this is updated whilst
91 * executing in the secure world.
92 */
93 .macro smccc_save_gp_mode_regs
94 /* Save r0 - r12 in the SMC context */
95 stm sp, {r0-r12}
96
Paul Beesley75017f22019-03-05 17:10:07 +000097.. _CVE-2018-19440: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-19440
Joel Hutton9e605632019-02-25 15:18:56 +000098.. _commit c385955: https://github.com/ARM-software/arm-trusted-firmware/commit/c385955
99.. _SMC Calling Convention: http://arminfo.emea.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
100.. _Pull Request #1710: https://github.com/ARM-software/arm-trusted-firmware/pull/1710