2020-5 android kernel vulnerability

谷梁煌
2023-12-01

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

触发方法:
  1. 在/ kernel / sched / Makefile文件中增加obj-y +=psi.o,增加该调度算法。
  2. 编译内核时会自动编译执行module_init(psi_proc_init);会在/proc目录下挂载一个/pressure目录作为用户态和内核交互的共享文件。
  3. 尝试用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

触发方法:
  1. 首先需要一个PEAK-System Technik USB接口的设备,而且使用双通道的CAN 2.0b适配器。
  2. 需要在Makefile中增加相应的pcan_usb_pro.o。
  3. 在驱动初始化启动完毕之后,会尝试向设备发送驱动准备完毕的信息,由于使用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

触发方法
  1. 首先,使用xfrm_user模块时,如果传递的sock是netlink_sock,就会把xfrm_netlink_rcv功能函数注册进一个netlink_sock的结构中的netlink_rcv字段中。

  2. 构造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

触发方法:
  1. 使用ioctl()调用kgsl_ioctl_gpu_command(),kgsl_gpu_command 结构体的numsyncs为1,numobjs为0来创建一个同步信号事件(指令集)。
  2. 在该事件过期之前,尝试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

触发方法
  1. 需要设备发送大量的数据包数据包需要是需要设定msm_vidc_core 的id参数为VIDC_HFI_VENUS,填充1000个数据包到,drvier中,
  2. 当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

触发方法:
  1. 在音频解析的第一步中,在pcm_native.c中会注册大量的file_operations。播放音频会调用.open函数,即snd_pcm_playback_open()函数,其中会搭建cpu与dsp通信的接口,叫做audio_client(高通特有的),继续下去调用adm_open等等,最后的adm_resiger会注册回调函数adm_callback。
  2. 回调函数需要两个参数,其中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
触发方法:

  1. 和CVE-2019-14038在同一个函数
  2. 回调函数的参数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
是什么:

数字信号处理器模块。

 类似资料: