Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
website
提交
b31e149c
W
website
项目概览
openeuler
/
website
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
W
website
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b31e149c
编写于
9月 01, 2020
作者:
J
Jiajie Li
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Li Jiajie post CVE-2020-14364 blog
上级
be37058a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
177 addition
and
0 deletion
+177
-0
content/zh/blog/lijiajie128/2020-09-01-CVE-2020-14364-QEMU-USB-array-out-of-range.md
.../2020-09-01-CVE-2020-14364-QEMU-USB-array-out-of-range.md
+177
-0
未找到文件。
content/zh/blog/lijiajie128/2020-09-01-CVE-2020-14364-QEMU-USB-array-out-of-range.md
0 → 100644
浏览文件 @
b31e149c
+++
title = "CVE-2020-14364 QEMU USB数组越界读写问题"
date = "2020-09-01"
tags = ["Qemu", "CVE", "USB", "Buffer overflow", "Patch"]
archives = "2020-09"
author = "Jiajie Li"
summary = "关于CVE-2020-14364的漏洞描述、分析以及针对性的解决方案"
+++
# CVE-2020-14364 QEMU USB数组越界读写问题
漏洞描述
====
QEMU(quick emulator)是一款由Fabrice Bellard等人编写的免费的可执行硬件虚拟化的开源托管虚拟机。其与Bochs,PearPC类似,但拥有高速(配合KVM),跨平台的特性。QEMU通过动态的二进制转换,模拟CPU,并且提供一组设备模型,使其能够运行多种未修改的客户机OS。通过QEMU与KVM一起使用,可以实现以接近本地速度来运行虚拟机,被广泛应用到虚拟化和云计算场景中。
近日360公司发现QEMU USB控制器模拟源代码hw/usb/core.c之中存在数组越界读写的问题,攻击者可以利用该漏洞获得qemu用户的执行权限进而实现
**完整的QEMU虚拟机逃逸**
。(CVE-2020-14364)
漏洞分析
====
*
经过分析,该漏洞存在于USB控制器模拟代码usb_process_one中,s->setup_len未经验证就赋值可能会引入的数组越界读写的风险 。由于libvirt启动的虚拟机默认会有配置有usb设备,而任何usb控制器(如uhci,ehci,xhci)与usb设备(如usb-tablet,usb-mouse等)之间交互都会经过core.c文件中的usb_process_one函数,因此理论上只要虚拟机有使用usb设备都存在漏洞攻击的风险。 此外,usb_process_one函数中可能进入的两个分支do_parameter和do_token_setup均存在该问题,即:
**在检查最终需要使用的数组长度前已经提前设置了该数组长度(s->setup_len)**
。
*
该漏洞的影响后果
**非常严重**
,因为攻击者可以利用该漏洞实现任意地址读取和写入,从而获得qemu进程的所有权限从而实现
**虚拟机逃逸**
,实现恶意代码执行攻击。此外,如果qemu进程处于root用户组那么攻击者就可以完整获得操作系统的控制权进而执行任意linux系统命令!
代码分析
----
```
c++
static
void
do_token_setup
(
USBDevice
*
s
,
USBPacket
*
p
)
{
int
request
,
value
,
index
;
if
(
p
->
iov
.
size
!=
8
)
{
p
->
status
=
USB_RET_STALL
;
return
;
}
usb_packet_copy
(
p
,
s
->
setup_buf
,
p
->
iov
.
size
);
s
->
setup_index
=
0
;
p
->
actual_length
=
0
;
s
->
setup_len
=
(
s
->
setup_buf
[
7
]
<<
8
)
|
s
->
setup_buf
[
6
];
//先对s->setup_len赋值
if
(
s
->
setup_len
>
sizeof
(
s
->
data_buf
))
{
// 后对setup_len进行合法性校验
fprintf
(
stderr
,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)
\n
"
,
s
->
setup_len
,
sizeof
(
s
->
data_buf
));
p
->
status
=
USB_RET_STALL
;
return
;
}
```
```
c++
static
void
do_parameter
(
USBDevice
*
s
,
USBPacket
*
p
)
{
int
i
,
request
,
value
,
index
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
s
->
setup_buf
[
i
]
=
p
->
parameter
>>
(
i
*
8
);
}
s
->
setup_state
=
SETUP_STATE_PARAM
;
s
->
setup_len
=
(
s
->
setup_buf
[
7
]
<<
8
)
|
s
->
setup_buf
[
6
];
//先对s->setup_len赋值
s
->
setup_index
=
0
;
request
=
(
s
->
setup_buf
[
0
]
<<
8
)
|
s
->
setup_buf
[
1
];
value
=
(
s
->
setup_buf
[
3
]
<<
8
)
|
s
->
setup_buf
[
2
];
index
=
(
s
->
setup_buf
[
5
]
<<
8
)
|
s
->
setup_buf
[
4
];
if
(
s
->
setup_len
>
sizeof
(
s
->
data_buf
))
{
// 后对setup_len进行合法性校验
fprintf
(
stderr
,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)
\n
"
,
s
->
setup_len
,
sizeof
(
s
->
data_buf
));
p
->
status
=
USB_RET_STALL
;
return
;
}
```
通过代码可以看到:do_token_setup以及do_parameter两个函数中,都在对s->setup_len做检查之前就设置了具体内容,并且当s->setup_len超出预定buffer大小之后,也没有对其进行更改,这使得其中被污染的数据依旧可以完成之后的越界读写功能。
影响性分析
----
1.
影响范围
QEMU 1.x 至今的QEMU的版本源代码之中均存在该漏洞,其中也包括了openEuler社区之前所使用的QEMU的代码。
2.
触发条件
触发该漏洞需要虚拟机至少连接有一个usb设备,而多数情况下libvirt会默认为虚拟机配置USB设备。
漏洞修复方法
----
根据360给出的修复方案,当检测到setup_len非法之后,将s->setup_len清零表示丢弃buffer中的USB请求,同时将USB的状态设置为SETUP_STATE_ACK,重新开始接受其他请求。补丁内容为:
```
c
Subject:
[
PATCH
]
hw
/
usb
/
core
.
c
fix
buffer
overflow
Store
calculated
setup_len
in
a
local
variable
,
verify
it
,
and
only
write
it
to
the
struct
(
USBDevice
->
setup_len
)
in
case
it
passed
the
sanity
checks
.
This
prevents
other
code
(
do_token_
{
in
,
out
}
function
specifically
)
from
working
with
invalid
USBDevice
->
setup_len
values
and
overruning
the
USBDevice
->
setup_buf
[]
buffer
.
Store
Fixes:
CVE
-
2020
-
14364
Signed
-
off
-
by
:
Gred
Hoffman
<
kraxel
@
redhat
.
com
>
---
hw
/
usb
/
core
.
c
|
4
++++
1
file
changed
,
4
insertions
(
+
)
diff
--
git
a
/
hw
/
usb
/
core
.
c
b
/
hw
/
usb
/
core
.
c
index
5
abd128b
..
12342
f13
100644
---
a
/
hw
/
usb
/
core
.
c
+++
b
/
hw
/
usb
/
core
.
c
@@
-
144
,
6
+
144
,
8
@@
static
void
do_token_setup
(
USBDevice
*
s
,
USBPacket
*
p
)
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)
\n
"
,
s
->
setup_len
,
sizeof
(
s
->
data_buf
));
p
->
status
=
USB_RET_STALL
;
+
s
->
setup_len
=
0
;
+
s
->
setup_state
=
SETUP_STATE_ACK
;
return
;
}
@@
-
277
,
6
+
279
,
8
@@
static
void
do_parameter
(
USBDevice
*
s
,
USBPacket
*
p
)
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)
\n
"
,
s
->
setup_len
,
sizeof
(
s
->
data_buf
));
p
->
status
=
USB_RET_STALL
;
+
s
->
setup_len
=
0
;
+
s
->
setup_state
=
SETUP_STATE_ACK
;
return
;
}
--
```
## 解决方案
*
下载openEuler发布最新的qemu软件包:
*
[
漏洞SA
](
https://cve.openeuler.org/#/infoDetails/openEuler-SA-2020-1061
)
*
[
aach64架构qemu软件包
](
[qemu-4.1.0-17.oe1.aarch64.rpm](https://repo.openeuler.org/openEuler-20.03-LTS/update/aarch64/Packages/qemu-4.1.0-17.oe1.aarch64.rpm
)
)
*
[
x86架构qemu软件包
](
https://repo.openeuler.org/openEuler-20.03-LTS/update/x86_64/Packages/qemu-4.1.0-17.oe1.x86_64.rpm
)
*
升级qemu软件包
*
rpm -Uvh qemu-
*
.rpm
*
升级完成之后查看qemu软件包的release号码,当release号大于等于17表示漏洞修复成功。
*
rpm -qi qemu-4.1.0
```
Name : qemu
Epoch : 2
Version : 4.1.0
Release : 17.oe1
Architecture: aarch64
Install Date: Mon 10 Aug 2020 04:53:20 PM CST
Group : Unspecified
Size : 19468602
License : GPLv2 and BSD and MIT and CC-BY
Signature : RSA/SHA1, Thu 09 Jul 2020 11:52:58 AM CST, Key ID d557065eb25e7f66
Source RPM : qemu-4.1.0-14.oe1.src.rpm
Build Date : Thu 09 Jul 2020 11:44:23 AM CST
Build Host : obs-worker-004
Packager : http://openeuler.org
Vendor : http://openeuler.org
URL : http://www.qemu.org
```
FAQ
====
1.
OpenEuler社区对此漏洞采取了什么措施?
社区相关人员得知漏洞之后,立刻制作出了相对应的补丁,并且第一时间将补丁合入社区相关分支之中。
2.
如何获取该漏洞的具体复现场景?
可以参考360在ISC2020第八届互联网安全大会上的分享:
*
https://isc.360.com/2020/detail.html?vid=108
*
https://www.anquanke.com/post/id/215405
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录