当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0141810

漏洞标题:cnm_jpu 驱动多个拒绝服务漏洞可造成内核崩溃

相关厂商:华为技术有限公司

漏洞作者: jiayy

提交时间:2015-10-13 12:20

修复时间:2016-01-14 09:36

公开时间:2016-01-14 09:36

漏洞类型:拒绝服务

危害等级:低

自评Rank:3

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-13: 细节已通知厂商并且等待厂商处理中
2015-10-16: 厂商已经确认,细节仅向厂商公开
2015-10-19: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航
2015-12-10: 细节向核心白帽子及相关领域专家公开
2015-12-20: 细节向普通白帽子公开
2015-12-30: 细节向实习白帽子公开
2016-01-14: 细节向公众公开

简要描述:

华为多款手机(如p8青春版,荣耀x2)使用了jpu驱动(/dev/cnm_jpu),该驱动在最新版本的实现里存在漏洞,system或者camera权限的恶意程序可以通过该驱动触发内核崩溃

详细说明:

测试平台: 华为P8 青春版
shell@hwALE-H:/ $ getprop ro.product.model
getprop ro.product.model
ALE-UL00
shell@hwALE-H:/ $ getprop ro.build.display.id
getprop ro.build.display.id
ALE-UL00 V100R001C00B131
驱动设备 :
crw-rw---- system camera 241, 0 2015-09-17 09:22 cnm_jpu
内核源码下载地址: http://**.**.**.**/cn/plugin.php?id=hwdownload&mod=detail&mid=144
出问题的文件:
kernel/drivers/vcodec/jpu/v8_jpu/jpu.c
kernel/drivers/vcodec/jpu/v8_jpu/jmm.h
kernel/drivers/vcodec/jpu/v3_jpu/jmm.h
kernel/drivers/vcodec/jpu/v3_jpu/jpu.c
问题代码:
jpu_ioctl 函数在处理 cmd = JDI_IOCTL_RESERVED_MEMORY_ALLOC 时有多处错误,
比如, jmem_init 函数内部,没有检测VMEM_P_ALLOC 返回值是否为 null 就直接操作会造成崩溃。
比如,
ERROR_RESERVED_MEMORY_ALLOC:
if (0 != ret)
{
jmem_exit(&s_jmem);
if (!IS_ERR((void *)s_jpeg_memory.base) && (s_jpeg_memory.base != 0))
{
ion_unmap_kernel(s_ion_client, s_ion_handle);
memset(&s_jpeg_memory, 0x00, sizeof(jpudrv_buffer_t));
}
这段代码里, 调用 ion_unmap_kernel 时, 变量s_ion_client, s_ion_handle没有检测是否为null,如果为null , 则程序会崩溃在 ion_unmap_kernel 函数里。而事实上,这两个变量在这里是有可能为空的

漏洞证明:

用测试代码在运行 /dev/cnm_gpu 的手机上,用 system或者camera或者root权限运行,100% 奔溃

修复方案:

这里只给出 jmem_init 函数的修复方案

int
jmem_init(
jpu_mm_t* mm,
unsigned long addr,
unsigned long size
)
{
int i;
if (NULL == mm)
return -1;
mm->base_addr = (addr+(JMEM_PAGE_SIZE-1))&~(JMEM_PAGE_SIZE-1);
mm->mem_size = size&~JMEM_PAGE_SIZE;
mm->num_pages = mm->mem_size/JMEM_PAGE_SIZE;
mm->page_list = (page_t*)VMEM_P_ALLOC(mm->num_pages*sizeof(page_t));
mm->free_tree = NULL;
mm->alloc_tree = NULL;
mm->free_page_count = mm->num_pages;
mm->alloc_page_count = 0;
for (i=0; i<mm->num_pages; i++) {
mm->page_list[i].pageno = i;
mm->page_list[i].addr = mm->base_addr + i*JMEM_PAGE_SIZE;
mm->page_list[i].alloc_pages = 0;
mm->page_list[i].used = 0;
mm->page_list[i].first_pageno = -1;
}
set_blocks_free(mm, 0, mm->num_pages);
return 0;
}


改成

int
jmem_init(
jpu_mm_t* mm,
unsigned long addr,
unsigned long size
)
{
int i;
if (NULL == mm)
return -1;
mm->base_addr = (addr+(JMEM_PAGE_SIZE-1))&~(JMEM_PAGE_SIZE-1);
mm->mem_size = size&~JMEM_PAGE_SIZE;
mm->num_pages = mm->mem_size/JMEM_PAGE_SIZE;
mm->page_list = (page_t*)VMEM_P_ALLOC(mm->num_pages*sizeof(page_t));
mm->free_tree = NULL;
mm->alloc_tree = NULL;
mm->free_page_count = mm->num_pages;
mm->alloc_page_count = 0;
if(mm->page_list==NULL) return -1;
for (i=0; i<mm->num_pages; i++) {
mm->page_list[i].pageno = i;
mm->page_list[i].addr = mm->base_addr + i*JMEM_PAGE_SIZE;
mm->page_list[i].alloc_pages = 0;
mm->page_list[i].used = 0;
mm->page_list[i].first_pageno = -1;
}
set_blocks_free(mm, 0, mm->num_pages);
return 0;
}

版权声明:转载请注明来源 jiayy@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:5

确认时间:2015-10-16 09:35

厂商回复:

感谢jiayy对华为公司安全的关注,我们已经将该漏洞通知了业务部门。

最新状态:

2015-12-17:目前该漏洞已发布了相关安全预警和修复补丁。再次感谢各位白帽子对华为公司安全的关注。