- CVE-2022-46316 Param Buffer Overflow in TA_fp_tee_get_indices
- HWPSIRT-2022-16269 Code Pointer Leak in lib_sync_sensor_info
- HWPSIRT-2022-64748 Lack of Locking when Accessing Global Variables
Param Buffer Overflow in TA_fp_tee_get_indices
¶
There is a buffer overflow on a TEE_Param
buffer in the command TA_fp_tee_get_indices
(ID #0x11).
TA_fp_tee_get_indices
calls fpc_ta_get_indices
, which expects a buffer and its size. However, in this case, the size comes from a user-controlled value stored in the first TEE_Param
parameter.
uint64_t TA_fp_tee_get_indices(uint32_t paramTypes, TEE_Param params[4]) {
// [...]
ret = fpc_ta_get_indices(params[1].memref.buffer, ¶ms[0].value.a);
// [...]
}
This address and the size are then propagated from fpc_ta_get_indices
to fpc_db_get_primary_and_privacy_fingerprint_indices
.
uint64_t fpc_ta_get_indices(void *obuf1_addr, unsigned int *ioval0_a_p) {
// [...]
indices = fpc_db_get_indices(
g_user_template_db,
fp_active_fingerprint_set_key,
obuf1_addr,
*ioval0_a_p,
ioval0_a_p);
// [...]
}
uint64_t fpc_db_get_indices(user_db_t *user_db, uint32_t key,
uint32_t *outbuf, uint32_t oufbuf_len, uint32_t *outbuf_count_p)
{
// [...]
fpc_db_get_primary_and_privacy_fingerprint_indices(
user_db, outbuf, oufbuf_len_, outbuf_count_p);
// [...]
}
And in fpc_db_get_primary_and_privacy_fingerprint_indices
, the length, which is user-controlled, is used to compute the end of the buffer to set all of its bytes to 0. If we specify a size that exceeds the actual length of the buffer an overflow occurs.
uint64_t fpc_db_get_primary_and_privacy_fingerprint_indices(user_db_t *user_db,
uint32_t *outbuf, uint32_t oufbuf_len, uint32_t *outbuf_count_p)
{
// [...]
curr_obuf_p = outbuf;
obuf_end = outbuf + oufbuf_len;
do
*curr_obuf_p++ = 0;
while ( v8 != v9 );
// [...]
}
This bug can be triggered using a proof of concept code results in the following output:
[HM] [ERROR][2171]vmem_as_ondemand_prepare failed
[HM] [ERROR][2496]process 1e00000028 (tid: 40) data abort:
[HM] [ERROR][2498]Bad memory access on address: 0x70005000, fault_code: 0x92000047
[HM]
[HM] Dump task states for tcb
[HM] ----------
[HM] name=[TA_uDFingerPrin] tid=40 is-idle=0 is-curr=0
[HM] state=BLOCKED@MEMFAULT sched.pol=0 prio=46 queued=1
[HM] aff[0]=ff
[HM] flags=0 smc-switch=0 ca=8053 prefer-ca=8053
[HM] Registers dump:
[HM] ----------
[HM] 64 bits userspace stack dump:
[HM] ----------
[HM] <fpc_db_get_primary_and_privacy_fingerprint_indices+0x40/0x164>
[HM] <fpc_db_get_indices>+0xf0/0x188
[HM] <fpc_db_get_indices>+0xf0/0x188
[HM] <fpc_ta_get_indices>+0x38/0xcc
[HM] <TA_fp_tee_get_indices>+0x98/0x140
[HM] <tee_task_entry>+0x7f0/0x868
[HM] <thread_func_wrapper>+0x34/0x58
[HM] Dump task states END
[HM]
Code Pointer Leak in lib_sync_sensor_info
¶
There are multiple code pointer leaks in lib_sync_sensor_info
. This function is used to resolve the addresses of library functions that can be called by the TA. After a function is resolved, its address is printed using SLog
, and thus accessible from the normal world using logcat
.
uint64_t lib_sync_sensor_info(...) {
// ...
lib_init_calibrate_dl = dlsym(g_palgorithm, "lib_init_calibrate_dl");
SLog("%s: lib:%s, func_name:%s, func:0x%x\n",
"sl_init_so_func", "g_palgorithm", "lib_init_calibrate_dl",
lib_init_calibrate_dl);
// ...
}
This bug can be triggered using a proof of concept code that results in the following output:
[TA_uDFingerPrint-1] [debug] 2685:TA_fp_init_so_lib:TA_fp_init_so_lib
[TA_uDFingerPrint-1] fpc_init_so_lib: sensor_type:0x1211
[TA_uDFingerPrint-1] fpc_init_so_lib: alg_lib_name:libalgorithm1211.so
[TA_uDFingerPrint-1] fpc_init_so_lib: algorithm dlopen start
[TA_uDFingerPrint-1] fpc_init_so_lib: p_lib_name:g_palgorithm, lib_name:libalgorithm1211.so, p_lib:0x3d116c0
[TA_uDFingerPrint-1] fpc_init_so_lib: algorithm lib dlopen success
[TA_uDFingerPrint-1] fpc_init_so_lib: p_algorithm:16843968
[TA_uDFingerPrint-1] fp_algorithm_func_dlsym: IN
[TA_uDFingerPrint-1] fp_algorithm_func_dlsym: lib:g_palgorithm, func_name:fp_init_alg_and_pp_lib, func:0x3d8e258
[TA_uDFingerPrint-1] fp_algorithm_func_dlsym: lib:g_palgorithm, func_name:fp_init_check_template_version, func:0x3d8e260
[TA_uDFingerPrint-1] fp_algorithm_func_dlsym: lib:g_palgorithm, func_name:fp_get_current_template_version, func:0x3d8e2e0
Lack of Locking when Accessing Global Variables¶
As visible in the logs when the trustlet is loaded, it is multi sessions. As a result, proper care must be taken when accessing or modifying global variables. Unfortunately, this trustlet is not doing any kind of locking, so many race conditions issues arise.
[GTask] TA name: TA_uDFingerPrint, UUID: a423e43d, ELF: 1461440, stack: 191072, heap: 29884416, multi session: True, keepalive: False, singleInstance: True
It should be possible to trigger double-frees, use-after-frees and various crashes by writing a multi-threaded CA that calls multiple commands concurrently. Race conditions could be triggered on the database, fingerprint set, and template objects (that are all heap-allocated and stored in global variables).
Proof of concept code that triggers race conditions using concurrent TA_fp_tee_init
results in the following crashes:
[HM] [ERROR][2171]vmem_as_ondemand_prepare failed
[HM] [ERROR][2496]process 220000003c (tid: 60) data abort:
[HM] [ERROR][2498]Bad memory access on address: 0x0, fault_code: 0x92000046
[HM]
[HM] Dump task states for tcb
[HM] ----------
[HM] name=[TA_uDFingerPrin] tid=60 is-idle=0 is-curr=0
[HM] state=BLOCKED@MEMFAULT sched.pol=0 prio=46 queued=1
[HM] aff[0]=ff
[HM] flags=0 smc-switch=0 ca=9177 prefer-ca=9177
[HM] Registers dump:
[HM] ----------
[HM] 64 bits userspace stack dump:
[HM] ----------
[HM] <memset+0xc/0xc8>
[HM] <gf_lib_secspi_write_flash>+0x264/0x2e8
[HM] <flash_deep_sleep>+0x70/0xb0
[HM] <lib_sync_sensor_info>+0x128/0xb64
[HM] <func_init_sensor>+0x850/0x8c4
[HM] <fp_init_sensor>+0x170/0x5c0
[HM] <fpc_ta_init>+0xac/0x2c8
[HM] <TA_fp_tee_init>+0x78/0xc8
[HM] <tee_task_entry>+0x7f0/0x868
[HM] <thread_func_wrapper>+0x34/0x58
[HM] Dump task states END
[HM]
[HM] [ERROR][2171]vmem_as_ondemand_prepare failed
[HM] [ERROR][2496]process 2200000036 (tid: 54) data abort:
[HM] [ERROR][2498]Bad memory access on address: 0x1, fault_code: 0x92000006
[HM]
[HM] Dump task states for tcb
[HM] ----------
[HM] name=[TA_uDFingerPrin] tid=54 is-idle=0 is-curr=0
[HM] state=BLOCKED@MEMFAULT sched.pol=0 prio=46 queued=1
[HM] aff[0]=ff
[HM] flags=0 smc-switch=0 ca=9179 prefer-ca=9179
[HM] Registers dump:
[HM] ----------
[HM] 64 bits userspace stack dump:
[HM] ----------
[HM] <memcpy+0x30/0x344>
[HM] <gf_lib_secspi_read_flash>+0x240/0x2e8
[HM] <flash_load_info>+0x68/0x17c
[HM] <flash_check_flash_version>+0x88/0x348
[HM] <lib_sync_sensor_info>+0x24c/0xb64
[HM] <func_init_sensor>+0x850/0x8c4
[HM] <fp_init_sensor>+0x170/0x5c0
[HM] <fpc_ta_init>+0xac/0x2c8
[HM] <TA_fp_tee_init>+0x78/0xc8
[HM] <tee_task_entry>+0x7f0/0x868
[HM] <thread_func_wrapper>+0x34/0x58
[HM] Dump task states END
[HM]
Affected Devices¶
We have verified that the vulnerabilities impacted the following device(s):
- Kirin 990: P40 Pro (ELS)
Please note that other models might have been affected.
Patch¶
Name | Severity | CVE | Patch |
---|---|---|---|
Param Buffer Overflow in TA_fp_tee_get_indices |
High | CVE-2022-46316 | December 2022 |
Code Pointer Leak in lib_sync_sensor_info |
Low | N/A | Fixed |
Lack of Locking when Accessing Global Variables | Low | N/A | Fixed |
Timeline¶
- Feb. 02, 2022 - A vulnerability report is sent to Huawei PSIRT.
- May 07, 2022 - Huawei PSIRT acknowledges the vulnerability report.
- Dec. 01, 2022 - Huawei PSIRT states that these issues were fixed in the December 2022 update.
- From Nov. 30, 2022 to Jul, 19 2023 - We exchange regularly about the release of our advisories.
- Jul. 03, 2023 - Huawei PSIRT informs us that some of the vulnerabilities are not patched and will be fixed in the August 2023 update.
Copyright © Impalabs 2021-2023