xref: /rk3399_ARM-atf/docs/security_advisories/security-advisory-tfv-1.rst (revision 4fe9123024b40706d8ec74224105814480a47931)
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