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