0x00 CVE-2020-0110(7.8)
发生位置:
psi.c(psi)的psi_write函数
补丁:
https://android-review.googlesource.com/c/kernel/common/+/1246698/1/kernel/sched/psi.c#1201
触发方法:
- 在/ kernel / sched / Makefile文件中增加obj-y +=psi.o,增加该调度算法。
- 编译内核时会自动编译执行module_init(psi_proc_init);会在/proc目录下挂载一个/pressure目录作为用户态和内核交互的共享文件。
- 尝试用io数据流的方式向该文件(pressure/io)写入0个字节的数据,会触发psi_write的越界写漏洞。
漏洞成因:
nbytes可以等于0,接下会出现逻辑错误,导致buf的-1位置被覆盖为/0。产生向上溢出。
修复方法:
加一个判断语句,让nbytes不能等于0。
时间:
2018-10-26至2020-2-29
是什么:
一个调度算法。
0x01 CVE-2019-19536(4.6)
发生位置:
linux内核版本低于5.2.9,drivers/net/can/usb/peak_usb/pcan_usb_pro.c
补丁:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ead16e53c2f0ed946d82d4037c630e2f60f4ab69
触发方法:
- 首先需要一个PEAK-System Technik USB接口的设备,而且使用双通道的CAN 2.0b适配器。
- 需要在Makefile中增加相应的pcan_usb_pro.o。
- 在驱动初始化启动完毕之后,会尝试向设备发送驱动准备完毕的信息,由于使用kmalloc()申请空间,未将原先的数据清0,会触发信息泄露,即urb结构体的transfer_buffer字段。具体泄露需要具体的设备。
漏洞成因:
分配的地址空间内容未置0,导致信息泄露。
修复方法:
更换内存分配函数,kmalloc()变成kzalloc()。添加kmalloc()的原因,
产生的功能用处
时间:
2013-06-03至2019-08-02
是什么:
pcan_usb设备的功能函数
0x02 CVE-2019-14053(7.1)
发生位置:
/net/xfrm/xfrm_user.c的validate_tmpl()
补丁:
https://source.codeaurora.org/quic/la/kernel/msm-4.9/commit/?id=a7afe21e5d65c74c7eacb6e577fa5cf78f8685fd
触发方法:
-
首先,使用xfrm_user模块时,如果传递的sock是netlink_sock,就会把xfrm_netlink_rcv功能函数注册进一个netlink_sock的结构中的netlink_rcv字段中。
-
构造netlink_sock数据包,使用sendmsg()函数进行发包,中间sk_buff的data字段指针所指向的区域必须是符合struct nlmsghdr,而且其中的nlmsg_type=XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE,才会触发漏洞。
漏洞成因:
xfrm_user模板xfrm_user_tmpl的mode参数没有规定范围,错误的绕过validate_tmpl,有越界读的风险。
修复方法:
增加判定函数。确保所有的模式只能选择已有的4种。
时间:
2006-12-03至2018-10-26
是什么:
xfrm可扩展安全框架(主要用来过滤数据包的)。
0x03 CVE-2020-3610(7.8)
发生位置:
/drivers/gpu/msm/kgsl_drawobj.c的drawobj_sync_func函数
补丁:
https://source.codeaurora.org/quic/la/kernel/msm-4.9/commit/?id=ae24933f4e3fd58ecbdd1463004f6112e7482793
触发方法:
- 使用ioctl()调用kgsl_ioctl_gpu_command(),kgsl_gpu_command 结构体的numsyncs为1,numobjs为0来创建一个同步信号事件(指令集)。
- 在该事件过期之前,尝试kgsl_context_dump()来调用kgsl_context_put()来减少目标event的refcount计数器到0,等待目标event的时间到期,从而自动释放,造成UAF。
漏洞成因:
drawobj_destroy_sync()会尝试释放掉当前同步信号对象(kgsl_drawobj_sync )的所有同步信号事件(kgsl_drawobj_sync_event ),释放完之后并没有将event的context字段调用kgsl_context_put来put,也就是context(struct kgsl_context)里的kgsl_event_group 也有该event的指针没有被释放掉。这导致其他context可以通过提前put掉context,来导致refcount计数器等于0,自动释放掉当even,来导致drawobj_destroy_sync()释放到该对象时产生UAF漏洞。
修复方法:
在drawobj_sync_func()中增加只有真正释放了对象,才对count进行操作,drawobj_destroy_sync()增加了校验代码,确保在释放的空间不是已经被释放过的。
时间:
2017-01-18到2019-07-26
是什么:
高通公司制作的3D图像驱动,主要是Adreno GPU系列,需要有图形化界面,处理器和Vulkan接口。kgsl_drawobj.c主要是一些同步信号的函数接口
0x04 CVE-2020-3630(7.8)
发生位置:
/drivers/media/platform/msm/vidc/venus_hfi.c,venus_hfi_core_release()的__get_q_size()函数
补丁:
https://source.codeaurora.org/quic/la/kernel/msm-4.9/commit/?id=056eb4a22db429af8445ee5aeda9976afdc86e98
触发方法:
- 需要设备发送大量的数据包数据包需要是需要设定msm_vidc_core 的id参数为VIDC_HFI_VENUS,填充1000个数据包到,drvier中,
- 当venus_hfi_core_work_handler函数被调用时,读取完1000个数据包后,会陷入死循环状态。
漏洞成因:
get_q_size()在queue为1000的时候,且都已经被查阅,会导致该函数永远返回0 ,response_handler会进入死循环。
修复方法:
删去该检查函数。
时间:
2017-02-09 到2020-01-02
是什么:
基于V4L2平台的视频设备驱动。venus_hfi.c是venus解码器。
0x05 CVE-2020-3680(7.0)
发生位置:
/drivers/char/adsprpc.c的fastrpc_internal_munmap_fd
补丁:
https://source.codeaurora.org/quic/la/kernel/msm-4.9/commit/?id=dc2091e9e4af87e8edaa328ec3a7192198b75669
触发方法:
直接调用fastrpc_device_ioctl,ioctl_num参数置为FASTRPC_IOCTL_MMAP或者FASTRPC_IOCTL_MMAP_64,与此同时再开一个线程ioctl_num参数置为FASTRPC_IOCTL_MUNMAP_FD来与原先的线程进行条件竞争,就有可能赢得race从而可以造成UAF。
漏洞成因:
fastrpc_internal_munmap_fd调用fastrpc_mmap_find来验证map的时候可能会产生窗口期,导致map提前被释放,但是map地址返回,可能会造成double free的风险。
修复方法:
加互斥锁。
时间:
2017-11-22至2020-01-21
是什么:
高通远程调用数字信号处理器驱动,依赖于MSM_GLINK。
0x06 CVE-2019-14087(7.8)
发生位置:
platform/hardware/qcom/display 的BuildLayerStack函数
补丁:
https://source.codeaurora.org/quic/la/platform/hardware/qcom/display/commit/?id=576a22370f673ac9aacc1d677a9a9d2a46ed05d2
触发方法:
使用HDR图像处理时,传入当前设备一张当前设备屏幕不支持的color mode。
漏洞成因:
由于没有对色彩模式进行判断,所以在不支持的色彩模式下,也会将layer->input_buffer.flags.hdr置为true,从而影响到Tonemapper的type字段变为TONEMAP_FORWARD,也就是HDR向SDR转换。
修复方法:
增加对当前设备色彩模式的判断
时间:
2017-11-29
是什么:
显示器,HRD显示模块。
0x07 CVE-2020-3615(9.8)
发生位置:
/core/wma/src/wma_mgmt.c的wma_is_pkt_drop_candidate
补丁:
https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/wlan/qcacld-3.0/commit/?id=8874df976ef96d715ea55d09676ff7b7fd338b13
触发方法:
远程(wife模式)向主机发送网络视频帧,发送的间隔小于WMA_MGMT_FRAME_DETECT_DOS_TIMER (1000ms),触发wma_is_pkt_drop_candidate的bug,导致正常报被丢弃。
漏洞成因:
接收到视频相关的网络数据包时wma_form_rx_packet会尝试将网络帧转化为连接驱动服务的数据包(cds package),此处会有wma_is_pkt_drop_candidate来检测是否为dos攻击,由于wma_is_pkt_drop_candidate中的*ptr无论在更新还是删除帧的时候都是增加的,所以只要一直连续不断的发送帧,帧会被一直丢掉,包括正常的帧。
修复方法:
改用qdf_system_time_before函数来判断。
时间:
2018-6-7至2019-12-23
是什么:
该文件是视窗媒体音频相关的STA/SAP/IBSS等wife模式和相关协议函数,该函数是防止dos攻击的接口,传送的网络帧需要满足IEEE80211要求。
0x08 CVE-2019-14038(7.1)
**发生位置:**root/dsp/q6adm.c的adm_callback
补丁:
https://source.codeaurora.org/quic/la/platform/vendor/opensource/audio-kernel/commit/?id=1587d00353aa5b1eb58a43b84195cb93df49cdb3
触发方法:
- 在音频解析的第一步中,在pcm_native.c中会注册大量的file_operations。播放音频会调用.open函数,即snd_pcm_playback_open()函数,其中会搭建cpu与dsp通信的接口,叫做audio_client(高通特有的),继续下去调用adm_open等等,最后的adm_resiger会注册回调函数adm_callback。
- 回调函数需要两个参数,其中apr_client_data中的opcode字段需要是ADM_CMDRSP_GET_PP_PARAMS_V5,apr_client_data的字段payload[3]表示拷贝数据的数量,当其大于apr_client_data的payload_size-16字节时,会发送payload的越界拷贝。
漏洞成因:
因为是payload[4]开始拷贝的,payload[3]存放的是参数的大小,所以如果payload_size-payload[3]<=4*sizeof(uint32_t),会将payload之后的数据越界写进adm_get_parameters中。
修复方法:
增加判断语句payload_size>= payload[3]+16
时间:
2017-8-18至2019-10-17
是什么:
QDSP6的系统级声卡驱动,q6adm.c主要是用来处理数字信号(adsp)的函数,adm_callback是声卡驱动管理器的回调函数。
0x09 CVE-2019-14039(7.1)
**发生位置:**root/dsp/q6adm.c的adm_callback
补丁:
https://source.codeaurora.org/quic/la/platform/vendor/opensource/audio-kernel/commit/?id=6afdb8bf450f0828e293bccc902333c5d10a1e0b
触发方法:
- 和CVE-2019-14038在同一个函数
- 回调函数的参数apr_client_data中的opcode字段需要是ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST,此时,apr_client_data的payload字段的前两个数组元素有特殊含义,payload[1]表示module的数量,payload[1]小于ADM_GET_TOPO_MODULE_LIST_LENGTH /4-1即可越界读取payload数组之后的数据。
漏洞成因:
如果payload_size减去payload[0]和payload[1]之后,大于拓扑结构中module的数量*每个模组的大小,会将payload之后的数据越界拷贝进adm_module_topo_list。
修复方法:
增加相应的判断语句。
时间:
2017-8-17至2019-9-6
是什么:
数字信号处理器模块。