1*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 2*4fe91230SJoel Hutton| Title | Malformed Firmware Update SMC can result in copy of | 3*4fe91230SJoel Hutton| | unexpectedly large data into secure memory | 4*4fe91230SJoel Hutton+================+=============================================================+ 5*4fe91230SJoel Hutton| CVE ID | CVE-2016-10319 | 6*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 7*4fe91230SJoel Hutton| Date | 18 Oct 2016 | 8*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 9*4fe91230SJoel Hutton| Versions | v1.2 and v1.3 (since commit `48bfb88`_) | 10*4fe91230SJoel Hutton| Affected | | 11*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 12*4fe91230SJoel Hutton| Configurations | Platforms that use AArch64 BL1 plus untrusted normal world | 13*4fe91230SJoel Hutton| Affected | firmware update code executing before BL31 | 14*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 15*4fe91230SJoel Hutton| Impact | Copy of unexpectedly large data into the free secure memory | 16*4fe91230SJoel Hutton| | reported by BL1 platform code | 17*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 18*4fe91230SJoel Hutton| Fix Version | `Pull Request #783`_ | 19*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 20*4fe91230SJoel Hutton| Credit | IOActive | 21*4fe91230SJoel Hutton+----------------+-------------------------------------------------------------+ 22*4fe91230SJoel Hutton 23*4fe91230SJoel HuttonGeneric Trusted Firmware (TF) BL1 code contains an SMC interface that is briefly 24*4fe91230SJoel Huttonavailable after cold reset to support the Firmware Update (FWU) feature (also 25*4fe91230SJoel Huttonknown as recovery mode). This allows most FWU functionality to be implemented in 26*4fe91230SJoel Huttonthe normal world, while retaining the essential image authentication 27*4fe91230SJoel Huttonfunctionality in BL1. When cold boot reaches the EL3 Runtime Software (for 28*4fe91230SJoel Huttonexample, BL31 on AArch64 systems), the FWU SMC interface is replaced by the EL3 29*4fe91230SJoel HuttonRuntime SMC interface. Platforms may choose how much of this FWU functionality 30*4fe91230SJoel Huttonto use, if any. 31*4fe91230SJoel Hutton 32*4fe91230SJoel HuttonThe BL1 FWU SMC handling code, currently only supported on AArch64, contains 33*4fe91230SJoel Huttonseveral vulnerabilities that may be exploited when *all* the following 34*4fe91230SJoel Huttonconditions apply: 35*4fe91230SJoel Hutton 36*4fe91230SJoel Hutton1. Platform code uses TF BL1 with the ``TRUSTED_BOARD_BOOT`` build option 37*4fe91230SJoel Hutton enabled. 38*4fe91230SJoel Hutton 39*4fe91230SJoel Hutton2. Platform code arranges for untrusted normal world FWU code to be executed in 40*4fe91230SJoel Hutton the cold boot path, before BL31 starts. Untrusted in this sense means code 41*4fe91230SJoel Hutton that is not in ROM or has not been authenticated or has otherwise been 42*4fe91230SJoel Hutton executed by an attacker. 43*4fe91230SJoel Hutton 44*4fe91230SJoel Hutton3. Platform code copies the insecure pattern described below from the ARM 45*4fe91230SJoel Hutton platform version of ``bl1_plat_mem_check()``. 46*4fe91230SJoel Hutton 47*4fe91230SJoel HuttonThe vulnerabilities consist of potential integer overflows in the input 48*4fe91230SJoel Huttonvalidation checks while handling the ``FWU_SMC_IMAGE_COPY`` SMC. The SMC 49*4fe91230SJoel Huttonimplementation is designed to copy an image into secure memory for subsequent 50*4fe91230SJoel Huttonauthentication, but the vulnerabilities may allow an attacker to copy 51*4fe91230SJoel Huttonunexpectedly large data into secure memory. Note that a separate vulnerability 52*4fe91230SJoel Huttonis required to leverage these vulnerabilities; for example a way to get the 53*4fe91230SJoel Huttonsystem to change its behaviour based on the unexpected secure memory contents. 54*4fe91230SJoel Hutton 55*4fe91230SJoel HuttonTwo of the vulnerabilities are in the function ``bl1_fwu_image_copy()`` in 56*4fe91230SJoel Hutton``bl1/bl1_fwu.c``. These are listed below, referring to the v1.3 tagged version 57*4fe91230SJoel Huttonof the code: 58*4fe91230SJoel Hutton 59*4fe91230SJoel Hutton- Line 155: 60*4fe91230SJoel Hutton 61*4fe91230SJoel Hutton .. code:: c 62*4fe91230SJoel Hutton 63*4fe91230SJoel Hutton /* 64*4fe91230SJoel Hutton * If last block is more than expected then 65*4fe91230SJoel Hutton * clip the block to the required image size. 66*4fe91230SJoel Hutton */ 67*4fe91230SJoel Hutton if (image_desc->copied_size + block_size > 68*4fe91230SJoel Hutton image_desc->image_info.image_size) { 69*4fe91230SJoel Hutton block_size = image_desc->image_info.image_size - 70*4fe91230SJoel Hutton image_desc->copied_size; 71*4fe91230SJoel Hutton WARN("BL1-FWU: Copy argument block_size > remaining image size." 72*4fe91230SJoel Hutton " Clipping block_size\n"); 73*4fe91230SJoel Hutton } 74*4fe91230SJoel Hutton 75*4fe91230SJoel Hutton /* Make sure the image src/size is mapped. */ 76*4fe91230SJoel Hutton if (bl1_plat_mem_check(image_src, block_size, flags)) { 77*4fe91230SJoel Hutton WARN("BL1-FWU: Copy arguments source/size not mapped\n"); 78*4fe91230SJoel Hutton return -ENOMEM; 79*4fe91230SJoel Hutton } 80*4fe91230SJoel Hutton 81*4fe91230SJoel Hutton INFO("BL1-FWU: Continuing image copy in blocks\n"); 82*4fe91230SJoel Hutton 83*4fe91230SJoel Hutton /* Copy image for given block size. */ 84*4fe91230SJoel Hutton base_addr += image_desc->copied_size; 85*4fe91230SJoel Hutton image_desc->copied_size += block_size; 86*4fe91230SJoel Hutton memcpy((void *)base_addr, (const void *)image_src, block_size); 87*4fe91230SJoel Hutton ... 88*4fe91230SJoel Hutton 89*4fe91230SJoel Hutton This code fragment is executed when the image copy operation is performed in 90*4fe91230SJoel Hutton blocks over multiple SMCs. ``block_size`` is an SMC argument and therefore 91*4fe91230SJoel Hutton potentially controllable by an attacker. A very large value may result in an 92*4fe91230SJoel Hutton integer overflow in the 1st ``if`` statement, which would bypass the check, 93*4fe91230SJoel Hutton allowing an unclipped ``block_size`` to be passed into 94*4fe91230SJoel Hutton ``bl1_plat_mem_check()``. If ``bl1_plat_mem_check()`` also passes, this may 95*4fe91230SJoel Hutton result in an unexpectedly large copy of data into secure memory. 96*4fe91230SJoel Hutton 97*4fe91230SJoel Hutton- Line 206: 98*4fe91230SJoel Hutton 99*4fe91230SJoel Hutton .. code:: c 100*4fe91230SJoel Hutton 101*4fe91230SJoel Hutton /* Make sure the image src/size is mapped. */ 102*4fe91230SJoel Hutton if (bl1_plat_mem_check(image_src, block_size, flags)) { 103*4fe91230SJoel Hutton WARN("BL1-FWU: Copy arguments source/size not mapped\n"); 104*4fe91230SJoel Hutton return -ENOMEM; 105*4fe91230SJoel Hutton } 106*4fe91230SJoel Hutton 107*4fe91230SJoel Hutton /* Find out how much free trusted ram remains after BL1 load */ 108*4fe91230SJoel Hutton mem_layout = bl1_plat_sec_mem_layout(); 109*4fe91230SJoel Hutton if ((image_desc->image_info.image_base < mem_layout->free_base) || 110*4fe91230SJoel Hutton (image_desc->image_info.image_base + image_size > 111*4fe91230SJoel Hutton mem_layout->free_base + mem_layout->free_size)) { 112*4fe91230SJoel Hutton WARN("BL1-FWU: Memory not available to copy\n"); 113*4fe91230SJoel Hutton return -ENOMEM; 114*4fe91230SJoel Hutton } 115*4fe91230SJoel Hutton 116*4fe91230SJoel Hutton /* Update the image size. */ 117*4fe91230SJoel Hutton image_desc->image_info.image_size = image_size; 118*4fe91230SJoel Hutton 119*4fe91230SJoel Hutton /* Copy image for given size. */ 120*4fe91230SJoel Hutton memcpy((void *)base_addr, (const void *)image_src, block_size); 121*4fe91230SJoel Hutton ... 122*4fe91230SJoel Hutton 123*4fe91230SJoel Hutton This code fragment is executed during the 1st invocation of the image copy 124*4fe91230SJoel Hutton operation. Both ``block_size`` and ``image_size`` are SMC arguments. A very 125*4fe91230SJoel Hutton large value of ``image_size`` may result in an integer overflow in the 2nd 126*4fe91230SJoel Hutton ``if`` statement, which would bypass the check, allowing execution to proceed. 127*4fe91230SJoel Hutton If ``bl1_plat_mem_check()`` also passes, this may result in an unexpectedly 128*4fe91230SJoel Hutton large copy of data into secure memory. 129*4fe91230SJoel Hutton 130*4fe91230SJoel HuttonIf the platform's implementation of ``bl1_plat_mem_check()`` is correct then it 131*4fe91230SJoel Huttonmay help prevent the above 2 vulnerabilities from being exploited. However, the 132*4fe91230SJoel HuttonARM platform version of this function contains a similar vulnerability: 133*4fe91230SJoel Hutton 134*4fe91230SJoel Hutton- Line 88 of ``plat/arm/common/arm_bl1_fwu.c`` in function of 135*4fe91230SJoel Hutton ``bl1_plat_mem_check()``: 136*4fe91230SJoel Hutton 137*4fe91230SJoel Hutton .. code:: c 138*4fe91230SJoel Hutton 139*4fe91230SJoel Hutton while (mmap[index].mem_size) { 140*4fe91230SJoel Hutton if ((mem_base >= mmap[index].mem_base) && 141*4fe91230SJoel Hutton ((mem_base + mem_size) 142*4fe91230SJoel Hutton <= (mmap[index].mem_base + 143*4fe91230SJoel Hutton mmap[index].mem_size))) 144*4fe91230SJoel Hutton return 0; 145*4fe91230SJoel Hutton 146*4fe91230SJoel Hutton index++; 147*4fe91230SJoel Hutton } 148*4fe91230SJoel Hutton ... 149*4fe91230SJoel Hutton 150*4fe91230SJoel Hutton This function checks that the passed memory region is within one of the 151*4fe91230SJoel Hutton regions mapped in by ARM platforms. Here, ``mem_size`` may be the 152*4fe91230SJoel Hutton ``block_size`` passed from ``bl1_fwu_image_copy()``. A very large value of 153*4fe91230SJoel Hutton ``mem_size`` may result in an integer overflow and the function to incorrectly 154*4fe91230SJoel Hutton return success. Platforms that copy this insecure pattern will have the same 155*4fe91230SJoel Hutton vulnerability. 156*4fe91230SJoel Hutton 157*4fe91230SJoel Hutton.. _48bfb88: https://github.com/ARM-software/arm-trusted-firmware/commit/48bfb88 158*4fe91230SJoel Hutton.. _Pull Request #783: https://github.com/ARM-software/arm-trusted-firmware/pull/783 159