Lucene search

K
seebugRootSSV:90067
HistoryDec 10, 2015 - 12:00 a.m.

QEMU pcnet_receive 堆缓冲区溢出漏洞(CVE-2015-7504)

2015-12-1000:00:00
Root
www.seebug.org
30

0.001 Low

EPSS

Percentile

32.1%

目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg06342.html

pcnet是虚拟化软件QEMU中实现AMD PCNET网卡功能模拟的组件,相关的代码实现位于/hw/net/pcnet.c中。

在qemu软件中使用pcnet网卡,需要如下的命令行进行配置:

qemu-system-x86_64 centos-6.5-x64.img -m 1024 - net nic,model=pcnet -net user

该漏洞发生在pcnet网卡模块的接收数据包的过程中,相关函数pcnet_receive的执行逻辑:首先检测CSR_DRX(s),CSR_STOP(s),CSR_SPND(s),size,CSR_LOOP(s),s->looptest这些值是否符合边界要求,确定函数是否继续处理。并且如果buf太小,则把它扩充到MIN_BUF_SIZE,之后检测是否要接受此包。最终把数据拷到rmd中物理地址中。相关代码截图如下:

在上述代码中,我们可以看到,在实现数据包buffer操作的逻辑时,程序员出现了一个明显的错误:未判断数据包的长度是否已经等于buffer长度。另外,在pcnet.c的另一个函数pcnet_transmit中也有对缓冲区位置和数据包长度的处理,截图如下:

如果数据包长度临近缓冲区长度(4096)时,由于代码逻辑会自动添加4个字节的crc值,因此就会发生缓冲区溢出。

巧合的是溢出了buffer之后的四个字节恰好会覆盖一个结构体指针。如图所示:

在溢出发生之后,代码流程进入pcnet_update_irq函数中,该函数经过层层调用,最终使用了irq->handler作为函数指针!!!而该irq的结构体指针我们可以对其进行控制,因此就完成了对代码逻辑的劫持。