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