SSD Advisory – Huawei P8 wkupccpu debugfs Kernel Buffer Overflow

Credit to Author: SSD / Maor Schwartz| Date: Sun, 17 Dec 2017 07:24:49 +0000

Want to get paid for a vulnerability similar to this one?
Contact us at: sxsxdx@xbxexyxoxnxdxsxexcxuxrxixtxy.xcom
See our full scope at:

Vulnerability Summary
The following advisory describes a buffer overflow found in Huawei P8 Lite ALE-21 HI621sft, operating system versions EMUI 3.1 – wkupccpu debugfs driver.

Huawei Technologies Co. Ltd. is “a multinational networking and telecommunications equipment and services company, it is the largest telecommunications equipment manufacturer in the world and the second largest smartphone manufacturer in the world”

A security researcher from, TRUEL IT, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program

Vendor response
Huawei confirmed that the vulnerability is not present on their most current version (with EMUI 4.0 or later), the only affected version is 3.1 and prior, it is recommended that all customers of Huawei upgrade to the latest version of their OS.

Vulnerability details
The vulnerability allows an attacker with root privileges in an unprivileged SELinux domain to execute arbitrary code in the kernel context.

The vulnerable code can be found in the wkupccpu debugfs driver.

File Kernel Binary Image – function pwrctrl_debug_init() @ 0xf9c714:

The instructions at offset 0xf9c78c and 0xf9c7b8 in the pwrctrl_debug_init function are the one responsible of registering the debugfs directory and file in the filesystem, which is then mounted within the /sys/kernel/debug/ system directory

The driver implements the write handler in its wkupccpu_dbgfs_write function:

It is good to have in mind the signature of a typical write implementation, which is:

The first basic block shown above prepares the stack and reserves 0xb0 (176) bytes for the local variables: register X1 will contain the pointer to const char * argument buffer provided by the user.

Lines from offset 0x666208 to 0x666218 are the one responsible to check if the pointer to const char * argument provided by the user and its size provided as the size_t argument can cause an arithmetic overflow.

In case of arithmetic overflow, the flow will be redirected to the basic block at offset 0x666234 and the vulnerability will not be triggered; otherwise, the execution will proceed to basic block at offset 0x666220, which contains the vulnerable copy_from_user call.

The following is the state of the registers when this call is reached:

  • X0 will hold the pointer to the destination buffer: the analysis highlights that the buffer is 0x8b (128) bytes longs and resides locally to the function
  • X1 will hold the pointer to the source buffer, which resides in user space and is usersupplied
  • X2 register will hold the number of bytes to copy, which is determined by the size ofthe buffer pointed by X1

Since we control the value of X2 register, we can provide a buffer wider than 128 bytes, causing an out-of-bounds write on the stack that could lead to memory corruption.

Proof of Concept
In order to exploit this vulnerability, the attacker is required to gain root privileges within any SELinux domain present in the device.

Looking at the SELinux policy extracted from the device, it is possible to note that debugfs SELinux context can be reached from the following domain:

The root privileges are necessary because of the following DAC permissions:

The vulnerability can be triggered by writing more than 128 bytes inside /sys/kernel/debug/wkupccpu_dbgfs/wkupccpu:

This results in a full control over the Program Counter (PC) register and the Link Register (LR), whichcould lead to code execution in the context of the kernel.

Print Friendly, PDF & Email