- CVE-2021-40017 Write of Arbitrary Data to sec_storage_data/PKI/
- CVE-2021-40040 Write of Controlled Params Set in generate_keyblob
- CVE-2021-46887 Integer Overflow in ber_pop_front
- HWPSIRT-2021-26563 Stack Address Leak in cmd_verify_key
- HWPSIRT-2021-07329 Integer Overflow in ber_init
- HWPSIRT-2021-63468 Logic Issue in verify_root_cert
- HWPSIRT-2021-73188 Stack Buffer Overflow in get_soter_cpuid
- HWPSIRT-2021-53224 OOB Access in get_soter_cpuid
We identified 3 vulnerabilities affecting Huawei's HW_KEYMASTER
trusted application that can be used to achieve code execution at S-EL0:
- write of arbitrary data to
sec_storage_data/PKI/
leading to arbitrary read of memory (and potentially even an arbitrary write); - write of controlled params set to an arbitrary memory address in
generate_keyblob
(name is our own); - integer overflow in
ber_pop_front
(name is our own) leading to an OOB read access to an arbitrary memory address.
We also identified 5 additional bugs affecting Huawei's HW_KEYMASTER
trusted application:
- a stack address leak in
cmd_verify_key
(name is our own); - an integer overflow in
ber_init
(name is our own); - a logic issue in
verify_root_cert
(name is our own); - a stack buffer overflow in
get_soter_cpuid
(name is our own); - an OOB access in
get_soter_cpuid
(name is our own).
Write of Arbitrary Data to sec_storage_data/PKI/
¶
The cmd_unwrap
function at 0x2C0F8 and the unwrap_asset_data_and_write_it_to_file
function at 0x2A1E8 can be used to write arbitrary data to any files in the sec_storage_data/PKI/
SFS folder. As the user can specify the key, nonce, and aad, they can send an input and tag that will result in a plaintext of their choosing. Thus, the filename and file data are fully controlled.
int cmd_unwrap(int paramTypes, TEE_Param params[4]) {
// ...
// wrap_key_type, associated_data, account_uid and assetstore_base_pwd
// are extracted from the params set contained in params[0]
params_from_key_params = get_params_from_key_params(
params[0].memref.buffer,
&wrap_key_type,
&associated_data,
&account_uid,
&assetstore_base_pwd);
// ...
// fst_alias and snd_alias (2 strings), and wrap_key_type (integer)
// are extracted as TLVs from params[1]
key_aliases = get_key_aliases(
params[1].memref.buffer,
params[1].memref.size,
&fst_alias,
&snd_alias,
wrap_key_type);
// ...
// we can specify wrap_key_type == 1
switch (wrap_key_type) {
case 1:
// if fst_alias is the alias of an AES key, its keymaterial
// will be retrieved from the SFS and put into key_param
get_aes_keymaterial_from_alias(&key_param, fst_alias.buf, fst_alias.len);
// ...
// a buffer of size 0x1000 is allocated to contain the plaintext
decrypt_data.buf = TEE_Malloc(0x1000, 0);
decrypt_data.len = 0x1000;
// ...
// the ciphertext contained in params[2] (as a TLV, alongside the nonce
// and tag) is decrypted using the aforementioned AES key, using the
// AES-256-CCM crypto algorithm (the AAD is derived from associated_data)
unwrap_asset_data_and_aes_decrypt(
key_param.buf,
key_param.len,
uid.buf,
uid.len,
¶ms[2].memref.buffer,
¶ms[2].memref.size,
&decrypt_data);
// ...
// unwrap_asset_data_and_write_it_to_file is called with the
// user-controlled plaintext and snd_alias
unwrap_asset_data_and_write_it_to_file(
decrypt_data.buf,
decrypt_data.len,
snd_alias.buf,
snd_alias.len,
¶ms[3]);
// ...
}
// ...
}
int unwrap_asset_data_and_write_it_to_file(
int *decrypt_buf,
int decrypt_len,
int snd_alias_buf,
int snd_alias_len,
TEE_Param *param3) {
// ...
tlv_buffer = decrypt_buf;
tlv_val_p = &tlv_val;
tlv_val.buf = 0;
tlv_val.len = 0;
tlv_size = decrypt_len;
expected_tags[0] = 2;
// ...
// tlv_val is extracted as an TLV value from the plaintext data
parse_unwrap_asset_data_tlv(&expected_tags, 1, &tlv_buffer, &tlv_size, &tlv_val_p);
// ...
// tlv_val is written to the SFS to the sec_storage_data/PKI/<snd_alias> file
write_data_to_file_by_alias(snd_alias_buf, snd_alias_len, tlv_val.buf, tlv_val.len);
// ...
}
This vulnerability has security implications as the sec_storage_data/PKI/
folder contains files of various types used by Keymaster (in particular keyblobs). Faking the content of keyblobs can lead to arbitrary reads, and potentially arbitrary writes as well, as we will see in the exploitation section.
Write of Controlled Params Set in generate_keyblob
¶
The generate_keyblob
function at 0xB0CC expects params[3]
to be a memref, as it will fill it with the params set of the keyblob that was just generated (using the resort_key_characteristics
function at 0xA1C8). However, there exists a code path reported below, that starts from cmd_begin
and allows reaching generate_keyblob
with a params[1]
that is a value and not a memref. This means that the params set data will be written to an arbitrary address. Furthermore, as the params set comes from params[1]
, the data written is also partially user-controlled.
The vulnerable code path is as follows:
cmd_begin
at 0xC540get_key_blob
at 0xBE60process_begin_for_keychain_new
at 0xBCC0generate_symmetric_keymaterial_special
at 0xBA98generate_keyblob
at 0xB0CCresort_key_characteristics
at 0xA1C8
int cmd_begin(unsigned int paramTypes, TEE_Param params[4]) {
// ...
get_key_blob(params, params_enforced, &key_blob, &vendor_type);
// ...
}
int get_key_blob(
TEE_Param *params,
unsigned int *params_enforced,
keyblob_t **keyblob_p,
int *vendor_type_p) {
// ...
return process_begin_for_keychain_new(v10, v13, v12, v11);
// ...
}
int process_begin_for_keychain_new(
int access_limit,
TEE_Param *params,
unsigned int *params_enforced,
keyblob_t **keyblob_p) {
// ...
generate_symmetric_keymaterial_special(key_data, 0x100u, &derive_factor, params, keyblob_p);
// ...
}
int generate_symmetric_keymaterial_special(
char *key_data,
unsigned int key_size,
key_param_t *derive_factor,
TEE_Param *params,
keyblob_t **keyblob_p) {
// ...
generate_keyblob(&derived_key, 0, params, 1, keyblob_p);
// ...
}
int generate_keyblob(
key_param_t *derived_key,
int a2,
TEE_Param *params,
int use_second_param,
keyblob_t **keyblob_p) {
// ...
if (use_second_param == 1)
params_set = params[1].memref.buffer;
else
params_set = params[0].memref.buffer;
// ...
keyblob = TEE_Malloc(0x1000u, 0);
keyblob->magic = 'HIKM';
keyblob->version = 0x12C;
memcpy_s(keyblob->blob, 0xFA0, derived_key->buf, derived_key->len);
keyblob->key_len = derived_key->len;
keyblob->key_off = 0x60;
// ...
hw_params_off = (derived_key->len + 0x63) & 0xFFFFFFFC;
hw_params_count = *(uint32_t *)params_set;
*(uint32_t *)(keyblob + hw_params_off) = hw_params_count;
memcpy_s(keyblob + hw_params_off + 4, 0xFFC - hw_params_off, params_set + 1, 0x10 * hw_params_count);
keyblob->hw_params_off = hw_params_off;
// ...
// copying of the sw_params in a similar fashion
// ...
// copying of the out-of-line params set data in a similar fashion
// ...
sort_params_set = params[3].memref.buffer;
if (!sort_params_set) // ...
sort_params_set_size = params[3].memref.size;
if (!sort_params_set_size) // ...
total_size = extra_end_offset - keyblob_->hw_params_off;
if (sort_params_set_size < total_size) // ...
resort_key_characteristics(sort_params_set, hw_params_ptr, total_size);
// ...
}
We demonstrate this arbitrary write in the exploitation section of this report.
Integer Overflow in ber_pop_front
¶
int ber_pop_front(ber_t *out_ber, ber_t *in_ber, int expected_type, int expected_class, int allowed_flag) {
// ...
read_ptr = in_ber->read_ptr;
// ...
tag = ber_read_byte(in_ber);
// ...
first_length = ber_read_byte(in_ber);
// ...
length = first_length;
if (first_length & 0x80) {
length = 0;
for (int i = 0; i < first_length & 0x7F; ++i)
length = ber_read_byte(in_ber) | (length << 8);
}
// ...
new_end = in_ber->read_ptr + length;
if (new_end <= in_ber->buf_end) {
in_ber->read_ptr = new_end;
out_ber->read_ptr = read_ptr;
out_ber->buf_end = new_end;
} else {
// ...
}
// ...
}
The ber_pop_front
function at 0x1D54 contains an integer overflow on the in_ber->read_ptr + length
addition. By specifying a negative value for length
, it is possible to make new_end
point before the start of the buffer. This pointer will then be used the next time ber_pop_front
is called to read a BER encoded value, which will result in a OOB read access.
We triggered this bug with a proof of concept and obtained the following crash at 0x2ebefec9 = 0x7000400a - 0x41414141
:
[HM] [ERROR][2171]vmem_as_ondemand_prepare failed
[HM] [ERROR][2496]process 2200000028 (tid: 40) data abort:
[HM] [ERROR][2498]Bad memory access on address: 0x2ebefec9, fault_code: 0x92000006
[HM]
[HM] Dump task states for tcb
[HM] ----------
[HM] name=[HW_KEYMASTER] 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=1000 smc-switch=0 ca=9358 prefer-ca=9358
[HM] Registers dump:
[HM] ----------
[HM] 32 bits userspace stack dump:
[HM] ----------
[HM] <?>+0x0/0x0
[HM] <TA_InvokeCommandEntryPoint>+0x64/0xd8
[HM] <tee_task_entry>+0x398/0xcd4
[HM] Dump task states END
[HM]
[HM] [TRACE][1212]pid=51 exit_status=130
Stack Address Leak in cmd_verify_key
¶
The cmd_verify_key
function at 0x39E80 contains a call to the SLog
function that will print the address of a stack variable. This log message can be retrieved using logcat
. We did not manage to trigger the call which is located in an error path.
.text:0003A3F4 LDR R1, =(aError - 0x3A408) ; "[Error]"
.text:0003A3F8 SUB R3, R11, #-a2
.text:0003A3FC LDR R0, =(aSCurrentCertIt - 0x3A40C) ; "%s: current cert iterator[%u] > count[%"...
.text:0003A400 ADD R1, PC, R1 ; "[Error]"
.text:0003A404 ADD R0, PC, R0 ; "%s: current cert iterator[%u] > count[%"...
.text:0003A408 BL SLog
Integer Overflow in ber_init
¶
The ber_init
function at 0x1FB8 contains an integer overflow on the buf + size
addition. We did not find a way to trigger this bug as the size comes from one of the TEE_Params
and their size is limited to 1 MB on the kernel side.
ber_t *ber_init(ber_t *ber, uint8_t *buf, uint32_t size, ber_state_t *state) {
state->error = 0;
state->error_ptr = 0;
ber->read_ptr = buf;
ber->buf_end = buf + size;
ber->state = state;
return ber;
}
int cmd_sop_decrypt(unsigned int paramTypes, TEE_Param params[4]) {
// ...
ibuf1_addr = params[1].memref.buffer;
if (!ibuf1_addr) // ...
// ...
ibuf1_size = params[1].memref.size;
if (!buf1_size) // ...
// ...
ber_init(&ber, ibuf1_addr, ibuf1_size, &state);
// ...
}
Logic Issue in verify_root_cert
¶
The verify_root_cert
function at 0x34700 is used to verify that the root certificate currently installed (saved on the SFS) is the same as the root certificate in the user-provided certificate chain. There is a logic issue on the comparison, as the error case is only taken if the sizes differ AND the contents differ (instead of OR). We did not evaluate the security impact of this bug.
unsigned int verify_root_cert(cert_entry_t *certs) {
// ...
cert_entry_t root_certs[3];
memset(root_certs, 0, sizeof(root_certs));
for (int i = 0; i < 3; ++i) {
cert_entry = get_cert_entry(1, 1, i, &root_certs[i]);
// ...
}
if (root_certs[2].len != certs[2].len
&& TEE_MemCompare(root_certs[2].buf, certs[2].buf, root_certs[2].len)) {
ret = -1;
SLog("%s: verifyRootCert fail\n\n", "[Error]");
}
free_certs(root_certs, 3);
return ret;
}
Stack Buffer Overflow in get_soter_cpuid
¶
The function get_soter_cpuid
at 0x18510 can overflow the buffer it is given as argument. If the size of the common_name
(extracted from a certificate that the user can set) is equal to the size of the buffer, the random hexadecimal string hexbuf
of size 9 will be written out of the buffer's bounds.
This function is called, via the get_soter_cntr_or_cpuid
function at 0x18794, in 3 places:
- in the
build_json_for_attestation
function at 0x18C1C - in the
build_json_message_to_sign
function at 0x18DCC - in the
build_soter_json_AK
function at 0x19BF8
In each of these cases, the overflowed buffer is allocated on the stack (and of size 0x80). We did not attempt to trigger this bug.
int build_json_for_attestation(int a1, int a2, int a3, int a4) {
// ...
char s[128];
// ...
memset(out_buf, 0, sizeof(out_buf));
out_buf_len = 0x80;
get_soter_cntr_or_cpuid(0, out_buf, &out_buf_len);
// ...
}
int get_soter_cntr_or_cpuid(int a1, char *out_buf, uint32_t *out_buf_len_p) {
get_soter_cpuid(out_buf, out_buf_len_p);
}
int get_soter_cpuid(char *out_buf, uint32_t *out_buf_len_p) {
char hexbuf[12];
// ...
cert_entry = get_cert_entry(1, 1, 0, &cert);
// ...
get_cert_dn_component_maybe(&component, 5u, cert.buf + 4, cert.len - 4);
while (component[0] != 6 || component[1] != 3 || TEE_MemCompare(component + 2, &g_common_name_oid, 3))
++component;
cpuid = component[5];
common_name_len = component[6];
common_name = component + 7;
out_buf_len = *out_buf_len_p;
component += 7;
if (out_buf_len < common_name_len) {
SLog("%s: out_buf_len:%u is less than cert_entry'CN:%d\n", "[Error]", out_buf_len, common_name_len);
goto LABEL_3;
}
TEE_MemMove(out_buf, common_name, common_name_len);
*out_buf_len_p = common_name_len;
// ...
rndbuf = TEE_Malloc(4, 0);
TEE_GenerateRandom(rndbuf, 4);
hexbuf[0] = 0x2D;
to_hex_string(rndbuf, 4, &hexbuf[1], 8u);
TEE_MemMove(&out_buf[*out_buf_len_p], hexbuf, 9u);
*out_buf_len_p += 9;
// ...
}
OOB Access in get_soter_cpuid
¶
The function get_soter_cpuid
at 0x18510 can also trigger an OOB access on component
if the certificate does not contain a common name. The while loop will continue incrementing component
indefinitely as long as the common name OID is not found.
int get_soter_cpuid(char *out_buf, uint32_t *out_buf_len_p) {
char hexbuf[12];
// ...
cert_entry = get_cert_entry(1, 1, 0, &cert);
// ...
get_cert_dn_component_maybe(&component, 5u, cert.buf + 4, cert.len - 4);
while (component[0] != 6 || component[1] != 3 || TEE_MemCompare(component + 2, &g_common_name_oid, 3))
++component;
// ...
}
Exploitation¶
We are going to exploit two of the vulnerabilities we mentioned to demonstrate that we can gain arbitrary read/write from these vulnerabilities. The vulnerabilities in question are the write of arbitrary data to sec_storage_data/PKI/
and the write of controlled params set in generate_keyblob
.
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.223
.
The trustlet binary MD5 checksum is as follows:
HWELS:/ # md5sum /vendor/bin/86310d18-5659-47c9-b212-841a3ca4f814.sec
e5b15daf991407ee3c440b98b7e5cb23 /vendor/bin/86310d18-5659-47c9-b212-841a3ca4f814.sec
Huawei's TEE OS iTrustee implements a whitelist mechanism that only allows specific client applications (native binaries or APKs) to talk to a trusted application.
In our case, the HW_KEYMASTER TA can only be called by the following CAs:
/system/bin/keystore
(uid 1017)/system/bin/vold
(uid 0)/vendor/bin/atcmdserver
(uid 0)/vendor/bin/hw_cert_service
(uid 0)/vendor/bin/hw/vendor.huawei.hardware.sop@1.0-service
(uid 1000)/system/bin/tee_test_ut
(uid 0)com.huawei.systemserver
(APK)com.huawei.hwonlineprovisionservice
(APK)
The authentication mechanism is implemented in 3 parts:
- the
teecd
daemon, that implements the TEE Client API, checks which native binary/APK is talking to it and sends that information to the kernel driver; - the kernel driver ensures that it is talking to
teecd
, and forwards the information it received to the TEE OS; - the TEE OS verifies that the client application is in the TA's whitelist.
Since we did not want to bother with injecting code in one of these binaries, we chose to circumvent the authentication by patching the kernel driver to add the ability to impersonate any native binary/APK.
Arbitrary Read¶
To trigger the write of arbitrary data to the SFS, we start by importing an all-zeroes AES key (with the alias key
) using the cmd_import_aes_key
command (ID 0x10003). We then prepare our file data by encrypting it using AES-256-CCM with the all-zeroes key, an all-zeroes IV, and the SHA256 hash of 86310d18-5659-47c9-b212-841a3ca4f814\x00...16 times...\x00
as the associated data. Finally, we call the cmd_unwrap
command (ID 0x1001) with the key
alias, all-zeroes IV, \x00...16 times...\x00
associated data, and the encrypted file data and tag that we calculated previously.
int cmd_get(unsigned int paramTypes, TEE_Param params[4]) {
// ...
ret = get_keyblob_from_alias(
&keyblob,
&keyblob_size,
params[0].memref.buffer,
params[0].memref.size,
params[2].value.a);
// ...
if (keyblob->magic == 0x534554
&& keyblob->version <= 0x12C
&& keyblob->keyblob_total_size == keyblob_size) {
memcpy_s(
params[1].memref.buffer,
params[1].memref.size,
keyblob + keyblob->key_off,
keyblob->key_len);
// ...
params[1].memref.size = keyblob->key_len;
}
// ...
}
To trigger a relative read, we write a "fake" keyblob to the sec_storage_data/PKI/blob
file, and call the cmd_get
command (ID 8) with the same file name. This command will read the blob
file and put its content into keyblob
. Since we can control the entire content of the keyblob file, we can pass the checks and have the command call memcpy_s
. memcpy_s
will copy into params[1]
from a user-controlled offset relative to the keyblob
object, and with a user-controlled size. Since the keyblob is heap-allocated, we can leak the content of the heap.
Here is an excerpt of the content of the heap:
...
X + 0x80 : 58 f0 c0 03 d0 89 fe 00 67 70 64 2e 74 61 2e 61 X.......gpd.ta.a
X + 0x90 : 70 70 49 44 00 18 0d 31 86 59 56 c9 47 b2 12 84 ppID...1.YV.G...
X + 0xa0 : 1a 3c a4 f8 14 00 00 00 41 00 00 00 41 00 00 00 .<......A...A...
X + 0xb0 : d8 89 fe 00 02 00 00 00 01 00 00 00 04 00 00 00 ................
X + 0xc0 : 90 89 fe 00 10 8a fe 00 67 70 64 2e 74 61 2e 73 ........gpd.ta.s
X + 0xd0 : 69 6e 67 6c 65 49 6e 73 74 61 6e 63 65 00 25 73 ingleInstance.%s
X + 0xe0 : 20 25 00 00 00 00 00 00 41 00 00 00 41 00 00 00 %......A...A...
X + 0xf0 : 18 8a fe 00 02 00 00 00 01 00 00 00 04 00 00 00 ................
X + 0x100: d0 89 fe 00 50 8a fe 00 67 70 64 2e 74 61 2e 6d ....P...gpd.ta.m
X + 0x110: 75 6c 74 69 53 65 73 73 69 6f 6e 00 25 73 20 25 ultiSession.%s %
X + 0x120: 00 00 00 00 00 00 00 00 41 00 00 00 41 00 00 00 ........A...A...
X + 0x130: 58 8a fe 00 02 00 00 00 01 00 00 00 04 00 00 00 X...............
...
To be able to read from arbitrary addresses, we need to leak the address of the keyblob
. When dumping the heap, we noticed that around the gpd.ta.appID
string were two pointers (one next
pointer at X + 0x84
, one prev
pointer at X + 0x100
) with the same value (d0 89 fe 00
in the dump above). Thanks to these pointers, we can deduce the address of the object located between them (X + 0xc0
in the dump above), and consequently of our keyblob
object.
We then used our arbitrary read, and the TALoader information leak, to find the base address of the trustlet. Finally, we use this address to dump the trustlet's memory as the final step of this demonstration.
Arbitrary Write¶
To trigger the arbitrary write to memory, we start by calling the cmd_on_user_event
command (ID 0x30001) with event_type == 2
. This will initialize the user keys that are required for the next step.
We then call the cmd_begin
command (ID 3) with the following param set values in params[1]
:
KM_TAG_VENDOR_TYPE
: 1KM_TAG_ASSETSTORE_ACCESSLIMITATION
: 2KM_TAG_PURPOSE
: 0x41414141KM_TAG_DERIVE_FACTOR
:\x00...16 times...\x00
0x90015FB9
:\x00\x00\x00\x00
These values allow reaching the code path presented in the vulnerability details. We specify the address we want to write to in params[3].value_a
and the size in params[3].value_b
. When these values are copied, the size we provide is checked and we need to make sure it's big enough to contain the values in the param set buffer. Finally, to show that we control some of the data being written, we chose to set a custom KM_TAG_PURPOSE
param value.
Note that if controlling more than 1/2/4/8 contiguous bytes of the data being written is needed, we could have also used a copyable tag of type KM_BYTES
, like 0x900002C3, 0x900002C4, or 0x900003EA that contains out-of-line data.
You can find below the output of the exploit running on our device:
adb wait-for-device shell su root sh -c "\"LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/poc\""
object is at 10c0910
ta_base_addr = 39ae000
TA memory dump:
0x039ae000: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF............
0x039ae010: 03 00 28 00 01 00 00 00 0c 1d 00 00 34 00 00 00 ..(.........4...
0x039ae020: dc 81 0b 00 00 02 00 05 34 00 20 00 05 00 28 00 ........4. ...(.
0x039ae030: 11 00 10 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
...
Writing a params set to an arbitrary address...
Reading the params set that was just written...
0x70000800: 05 00 00 00 01 00 00 20 00 00 00 00 41 41 41 41 ....... ....AAAA
0x70000810: 00 00 00 00 be 02 00 10 2c f8 a9 03 00 00 00 00 ........,.......
0x70000820: 04 fa a9 03 c1 02 00 30 00 00 00 00 00 00 00 00 .......0........
0x70000830: 00 00 00 00 c2 02 00 30 00 00 00 00 00 00 00 00 .......0........
...
Getting Code Execution¶
While it is not included in the exploit, it is possible to get code execution by replacing a function pointer/overwriting a return address, and chaining ROP gadgets. There are plenty of gadgets to choose from as the shared libraries (libc_shared_a32.so
, libtee_shared_a32.so
, libvendor_shared_a32.so
, etc.) are mapped in the trustlet's address space.
For example, this could be used to make arbitrary syscalls and potentially further escalate privileges.
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 |
---|---|---|---|
Write of Arbitrary Data to sec_storage_data/PKI/ |
Critical | CVE-2021-40017 | September 2022 |
Write of Controlled Params Set in generate_keyblob |
Critical | CVE-2021-40040 | September 2022 |
Integer Overflow in ber_pop_front |
High | CVE-2021-46887 | May 2023 |
Stack Address Leak in cmd_verify_key |
Low | N/A | Fixed |
Integer Overflow in ber_init |
Low | N/A | Fixed |
Logic Issue in verify_root_cert |
Low | N/A | Fixed |
Stack Buffer Overflow in get_soter_cpuid |
Low | N/A | Fixed |
OOB Access in get_soter_cpuid |
Low | N/A | Fixed |
Timeline¶
- Nov. 24, 2021 - A vulnerability report is sent to Huawei PSIRT.
- Jan. 12, 2022 - Huawei PSIRT acknowledges the vulnerability report.
- May 01, 2023 - Huawei PSIRT states that these issues are fixed in the September 2022 and May 2023 updates.
- From Nov. 30, 2022 to Jul, 19 2023 - We exchange regularly about the release of our advisories.
- Jun. 21, 2023 - We inform Huawei PSIRT that some of the vulnerabilities are not patched.
- Jul. 03, 2023 - Huawei PSIRT replies that they will be fixed in the August 2023 update.
Copyright © Impalabs 2021-2023