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