123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- Advisory TFV-1 (CVE-2016-10319)
- ===============================
- +----------------+-------------------------------------------------------------+
- | Title | Malformed Firmware Update SMC can result in copy of |
- | | unexpectedly large data into secure memory |
- +================+=============================================================+
- | CVE ID | `CVE-2016-10319`_ |
- +----------------+-------------------------------------------------------------+
- | Date | 18 Oct 2016 |
- +----------------+-------------------------------------------------------------+
- | Versions | v1.2 and v1.3 (since commit `48bfb88`_) |
- | Affected | |
- +----------------+-------------------------------------------------------------+
- | Configurations | Platforms that use AArch64 BL1 plus untrusted normal world |
- | Affected | firmware update code executing before BL31 |
- +----------------+-------------------------------------------------------------+
- | Impact | Copy of unexpectedly large data into the free secure memory |
- | | reported by BL1 platform code |
- +----------------+-------------------------------------------------------------+
- | Fix Version | `Pull Request #783`_ |
- +----------------+-------------------------------------------------------------+
- | Credit | IOActive |
- +----------------+-------------------------------------------------------------+
- Generic Trusted Firmware (TF) BL1 code contains an SMC interface that is briefly
- available after cold reset to support the Firmware Update (FWU) feature (also
- known as recovery mode). This allows most FWU functionality to be implemented in
- the normal world, while retaining the essential image authentication
- functionality in BL1. When cold boot reaches the EL3 Runtime Software (for
- example, BL31 on AArch64 systems), the FWU SMC interface is replaced by the EL3
- Runtime SMC interface. Platforms may choose how much of this FWU functionality
- to use, if any.
- The BL1 FWU SMC handling code, currently only supported on AArch64, contains
- several vulnerabilities that may be exploited when *all* the following
- conditions apply:
- 1. Platform code uses TF BL1 with the ``TRUSTED_BOARD_BOOT`` build option
- enabled.
- 2. Platform code arranges for untrusted normal world FWU code to be executed in
- the cold boot path, before BL31 starts. Untrusted in this sense means code
- that is not in ROM or has not been authenticated or has otherwise been
- executed by an attacker.
- 3. Platform code copies the insecure pattern described below from the ARM
- platform version of ``bl1_plat_mem_check()``.
- The vulnerabilities consist of potential integer overflows in the input
- validation checks while handling the ``FWU_SMC_IMAGE_COPY`` SMC. The SMC
- implementation is designed to copy an image into secure memory for subsequent
- authentication, but the vulnerabilities may allow an attacker to copy
- unexpectedly large data into secure memory. Note that a separate vulnerability
- is required to leverage these vulnerabilities; for example a way to get the
- system to change its behaviour based on the unexpected secure memory contents.
- Two of the vulnerabilities are in the function ``bl1_fwu_image_copy()`` in
- ``bl1/bl1_fwu.c``. These are listed below, referring to the v1.3 tagged version
- of the code:
- - Line 155:
- .. code:: c
- /*
- * If last block is more than expected then
- * clip the block to the required image size.
- */
- if (image_desc->copied_size + block_size >
- image_desc->image_info.image_size) {
- block_size = image_desc->image_info.image_size -
- image_desc->copied_size;
- WARN("BL1-FWU: Copy argument block_size > remaining image size."
- " Clipping block_size\n");
- }
- /* Make sure the image src/size is mapped. */
- if (bl1_plat_mem_check(image_src, block_size, flags)) {
- WARN("BL1-FWU: Copy arguments source/size not mapped\n");
- return -ENOMEM;
- }
- INFO("BL1-FWU: Continuing image copy in blocks\n");
- /* Copy image for given block size. */
- base_addr += image_desc->copied_size;
- image_desc->copied_size += block_size;
- memcpy((void *)base_addr, (const void *)image_src, block_size);
- ...
- This code fragment is executed when the image copy operation is performed in
- blocks over multiple SMCs. ``block_size`` is an SMC argument and therefore
- potentially controllable by an attacker. A very large value may result in an
- integer overflow in the 1st ``if`` statement, which would bypass the check,
- allowing an unclipped ``block_size`` to be passed into
- ``bl1_plat_mem_check()``. If ``bl1_plat_mem_check()`` also passes, this may
- result in an unexpectedly large copy of data into secure memory.
- - Line 206:
- .. code:: c
- /* Make sure the image src/size is mapped. */
- if (bl1_plat_mem_check(image_src, block_size, flags)) {
- WARN("BL1-FWU: Copy arguments source/size not mapped\n");
- return -ENOMEM;
- }
- /* Find out how much free trusted ram remains after BL1 load */
- mem_layout = bl1_plat_sec_mem_layout();
- if ((image_desc->image_info.image_base < mem_layout->free_base) ||
- (image_desc->image_info.image_base + image_size >
- mem_layout->free_base + mem_layout->free_size)) {
- WARN("BL1-FWU: Memory not available to copy\n");
- return -ENOMEM;
- }
- /* Update the image size. */
- image_desc->image_info.image_size = image_size;
- /* Copy image for given size. */
- memcpy((void *)base_addr, (const void *)image_src, block_size);
- ...
- This code fragment is executed during the 1st invocation of the image copy
- operation. Both ``block_size`` and ``image_size`` are SMC arguments. A very
- large value of ``image_size`` may result in an integer overflow in the 2nd
- ``if`` statement, which would bypass the check, allowing execution to proceed.
- If ``bl1_plat_mem_check()`` also passes, this may result in an unexpectedly
- large copy of data into secure memory.
- If the platform's implementation of ``bl1_plat_mem_check()`` is correct then it
- may help prevent the above 2 vulnerabilities from being exploited. However, the
- ARM platform version of this function contains a similar vulnerability:
- - Line 88 of ``plat/arm/common/arm_bl1_fwu.c`` in function of
- ``bl1_plat_mem_check()``:
- .. code:: c
- while (mmap[index].mem_size) {
- if ((mem_base >= mmap[index].mem_base) &&
- ((mem_base + mem_size)
- <= (mmap[index].mem_base +
- mmap[index].mem_size)))
- return 0;
- index++;
- }
- ...
- This function checks that the passed memory region is within one of the
- regions mapped in by ARM platforms. Here, ``mem_size`` may be the
- ``block_size`` passed from ``bl1_fwu_image_copy()``. A very large value of
- ``mem_size`` may result in an integer overflow and the function to incorrectly
- return success. Platforms that copy this insecure pattern will have the same
- vulnerability.
- .. _CVE-2016-10319: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10319
- .. _48bfb88: https://github.com/ARM-software/arm-trusted-firmware/commit/48bfb88
- .. _Pull Request #783: https://github.com/ARM-software/arm-trusted-firmware/pull/783
|