Huawei Secure Monitor Vulnerabilities

We discussed this vulnerability during Episode 176 on 13 December 2022

Excellent post covering three vulnerabilities in Huawei’s Secure Monitor used to proxy/transition requests from the “normal world” usually from the hypervisor or kernel into the secure world.

SMC SE Factory Check OOB Access - CVE-2021-39994 For communication between the normal and secure world a shared memory buffer is used and should exist within a specific contiguous region (0x40000000-0x50000000). An incoming command will include an address to the shared buffer that the output should be written to. There is a function se_smc_addr_check which is used to ensure that the address and the data size is completely contained within the expected region.

This function is used inconsistently and there are some commands that do not actually check the bounds of the provided address, allowing an attacker to have output written into the secure world memory. se_factory_check is one of these functions. It will write a code value out to the provided address. Allowing them to clobber other sensitive values.


The mntn system supports some of the logging functionality, and provides a way to get logs from the secure system. The first command to the system should be the init command which sets up the physical address and size of the shared buffer to use, it then allocates the shared buffer. It does attempt to ensure the buffer will be in the appropriate range:

// Check (improperly) that the buffer is in the address range 0x3c000000-0x40000000.
if (buf_addr >= 0x3c000000 && buf_addr + buf_size - 1 < 0x40000000) {

The problem is that buf_addr + buf_size can overflow, resulting in a value smaller than the limit so the checks pass.

SMC MNTN - Shared Control Structure

There is a second issue in the mntn code. The system will write a control structure to the head of the buffer. This structure (hlog_header) contains the relevant meta-data for writing to the log. It tracks the address, along size the current position and maximum size. The problem here is that the shared buffer, is, well, shared. As teh control structure is within the buffer, the kernel (normal world) can tamper with any of these values and control where logs will be written.

The post also goes into exploitation of the above issues to gain secure world code execution.