impalabs space base graphics
Huawei TrustZone TALoader Information Leak
This advisory contains information about the following vulnerabilities:

Generic ASLR Bypass Using TALoader's Information

We identified a vulnerability affecting the TALoader binary that can be leveraged by any trusted application to leak its base address and other information related to its memory mappings.

During the loading of a trusted application, the TALoader binary will fill a page at a fixed address with information related to the trusted application memory mapping. If an attacker is able to read memory arbitrarily in the trustlet's address space, they can leak its base address, thus defeating ASLR in a generic and deterministic way.

The e9b92e05c2ff09e8 function of the TALoader binary calls mmap to map into memory the trusted application binary. The base address of the TA, which is randomized to make it harder for an attacker to compromise the TA, is then passed to the 5342f1ac85e313fa function.

int e9b92e05c2ff09e8(int a1, int a2, int a3, int a4) {
    // [...]
    ta_base_addr = mmap(0, size, 3, 0x22, 0xFFFFFFFF, offset);
    if (ta_base_addr == 0xFFFFFFFF) {
        std_log("ERROR", "*", 0x92A, "map failed\n");
        goto MAP_FAILED;
    }
    // [...]
    ret = 5342f1ac85e313fa(ta_base_addr, ta_size, dyn_info);
    // [...]
}

The 5342f1ac85e313fa function will fill the page at address 0x70000000 with entries containing information about the TA's memory mappings. We can see that the base address of the binary is written at offset 0x20 into one of the entries.

int 5342f1ac85e313fa(int ta_base_addr, int ta_size, uint32_t *dyn_info) {
    // [...]

    if (ta_base_addr == 0 || dyn_info == 0)  {
        std_log("ERROR", "*", 0x65, "input is invalid!");
        return -1;
    }

    infoleak = 0x70000000;
    while (*(uint64_t *)infoleak) {
        infoleak += 0x28;
        if (infoleak == 0x70000FF0)
            return 0;
    }

    syment_count = *(uint32_t *)(ta_base_addr + dyn_info[DT_HASH] + 4);
    symtab_addr = dyn_info[DT_SYMTAB];
    if (syment_count > (ta_size - symtab_addr) >> 4) {
        std_log("ERROR", "*", 0x72, "too many symbols\n");
        return -1;
    }

    syment_size = dyn_info[DT_SYMENT];
    *(uint32_t *)(infoleak + 0) = ta_base_addr + symtab_addr;
    strtab_addr = dyn_info[DT_STRTAB];
    strtab_size = dyn_info[DT_STRSZ];
    *(uint32_t *)(infoleak + 4) = 0;
    *(uint64_t *)(infoleak + 8) = syment_size * syment_count;
    *(uint32_t *)(infoleak + 0x10) = ta_base_addr + strtab_addr;
    *(uint32_t *)(infoleak + 0x14) = 0;
    *(uint32_t *)(infoleak + 0x18) = strtab_size;
    *(uint32_t *)(infoleak + 0x1C) = 0;
    *(uint32_t *)(infoleak + 0x20) = ta_base_addr;
    *(uint32_t *)(infoleak + 0x24) = 0;
    return 0;
}

Exploitation

Our Device Setup

The device we have developed an exploit for is a P40 Pro running the firmware update ELS-LGRP4-OVS_11.0.0.196. The binary's MD5 checksum is the following:

$ md5 taloader.elf
MD5 (taloader.elf) = fb1fc3669eb5fd100891b30e104bfdea

ALSR Slide Leak

Empirically and using knowledge from past exploits, we have observed that the entry referring to the trusted application binary is always the 5th, so the TA base address is always at 0x70000000 + 4 * 0x28 + 0x20 = 0x700000c0.

To demonstrate this vulnerability, we have used the TA_SignTool exploit. By adapting this exploit with the following code, we will be able to leak the base address of the targeted trusted application:

// Demonstrate the arbitrary read by dumping trustlet memory
uint32_t ta_base_addr;
signtool_read(fd, &context, 0x700000c0, 4, &ta_base_addr);
printf("ta_base_addr = %x\n", ta_base_addr);

The exploit output indeed shows the expected result:

ta_base_addr = 380d000

Affected Devices

We have verified that the vulnerability impacted the following device(s):

  • Kirin 990: P40 Pro (ELS)

Please note that other models might have been affected.

Patch

Name Severity CVE Patch
Generic ASLR Bypass Using TALoader's Information Medium CVE-2021-40023 September 2022

Timeline

  • Oct. 08, 2021 - A vulnerability report is sent to Huawei PSIRT.
  • Oct. 19, 2021 - Huawei PSIRT inquires about our reverse engineering process (i.e. how the TEE image and TA files are decrypted) and how normal world kernel verifications are bypassed to communicate with the secure world.
  • Oct. 19, 2021 - A response is sent to Huawei PSIRT.
  • Oct. 25, 2021 - Huawei PSIRT acknowledges the vulnerability report.
  • Sep. 01, 2022 - Huawei PSIRT states that these issues were fixed in the September 2022 update.
  • From Nov. 30, 2022 to Jul, 19 2023 - We exchange regularly about the release of our advisories.