summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Sakoman <steve@sakoman.com>2020-10-27 06:45:19 -1000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-11-03 08:19:34 +0000
commita34ac11f38066d086ab286f24e56d81e0d5706f1 (patch)
tree5e71d77555a2842095fd58dfaad5133685e36884
parent7fa82508276888f0eb413bfc79c732bb12ca57b1 (diff)
downloadpoky-a34ac11f38066d086ab286f24e56d81e0d5706f1.tar.gz
qemu: fix CVE-2019-20175
CVE: CVE-2019-20175 (From OE-Core rev: dc91e39e6a5c117a2fec7afc2bab683ff0ab096a) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/qemu/qemu.inc1
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2019-20175.patch94
2 files changed, 95 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index 76f97eef35..b6941403ea 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -49,6 +49,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
49 file://CVE-2020-14415.patch \ 49 file://CVE-2020-14415.patch \
50 file://CVE-2020-16092.patch \ 50 file://CVE-2020-16092.patch \
51 file://0001-target-mips-Increase-number-of-TLB-entries-on-the-34.patch \ 51 file://0001-target-mips-Increase-number-of-TLB-entries-on-the-34.patch \
52 file://CVE-2019-20175.patch \
52 " 53 "
53UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" 54UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
54 55
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2019-20175.patch b/meta/recipes-devtools/qemu/qemu/CVE-2019-20175.patch
new file mode 100644
index 0000000000..cbbb6d094c
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2019-20175.patch
@@ -0,0 +1,94 @@
1From ed78352a59ea7acf7520d4d47a96b9911bae7fc3 Mon Sep 17 00:00:00 2001
2From: Alexander Popov <alex.popov@linux.com>
3Date: Mon, 23 Dec 2019 20:51:16 +0300
4Subject: [PATCH] ide: Fix incorrect handling of some PRDTs in ide_dma_cb()
5
6The commit a718978ed58a from July 2015 introduced the assertion which
7implies that the size of successful DMA transfers handled in ide_dma_cb()
8should be multiple of 512 (the size of a sector). But guest systems can
9initiate DMA transfers that don't fit this requirement.
10
11For fixing that let's check the number of bytes prepared for the transfer
12by the prepare_buf() handler. The code in ide_dma_cb() must behave
13according to the Programming Interface for Bus Master IDE Controller
14(Revision 1.0 5/16/94):
151. If PRDs specified a smaller size than the IDE transfer
16 size, then the Interrupt and Active bits in the Controller
17 status register are not set (Error Condition).
182. If the size of the physical memory regions was equal to
19 the IDE device transfer size, the Interrupt bit in the
20 Controller status register is set to 1, Active bit is set to 0.
213. If PRDs specified a larger size than the IDE transfer size,
22 the Interrupt and Active bits in the Controller status register
23 are both set to 1.
24
25Signed-off-by: Alexander Popov <alex.popov@linux.com>
26Reviewed-by: Kevin Wolf <kwolf@redhat.com>
27Message-id: 20191223175117.508990-2-alex.popov@linux.com
28Signed-off-by: John Snow <jsnow@redhat.com>
29
30Upstream-Status: Backport
31CVE: CVE-2019-20175
32Signed-off-by: Steve Sakoman <steve@sakoman.com>
33
34---
35 hw/ide/core.c | 30 ++++++++++++++++++++++--------
36 1 file changed, 22 insertions(+), 8 deletions(-)
37
38diff --git a/hw/ide/core.c b/hw/ide/core.c
39index 754ff4dc343..80000eb7661 100644
40--- a/hw/ide/core.c
41+++ b/hw/ide/core.c
42@@ -849,6 +849,7 @@ static void ide_dma_cb(void *opaque, int ret)
43 int64_t sector_num;
44 uint64_t offset;
45 bool stay_active = false;
46+ int32_t prep_size = 0;
47
48 if (ret == -EINVAL) {
49 ide_dma_error(s);
50@@ -863,13 +864,15 @@ static void ide_dma_cb(void *opaque, int ret)
51 }
52 }
53
54- n = s->io_buffer_size >> 9;
55- if (n > s->nsector) {
56- /* The PRDs were longer than needed for this request. Shorten them so
57- * we don't get a negative remainder. The Active bit must remain set
58- * after the request completes. */
59+ if (s->io_buffer_size > s->nsector * 512) {
60+ /*
61+ * The PRDs were longer than needed for this request.
62+ * The Active bit must remain set after the request completes.
63+ */
64 n = s->nsector;
65 stay_active = true;
66+ } else {
67+ n = s->io_buffer_size >> 9;
68 }
69
70 sector_num = ide_get_sector(s);
71@@ -892,9 +895,20 @@ static void ide_dma_cb(void *opaque, int ret)
72 n = s->nsector;
73 s->io_buffer_index = 0;
74 s->io_buffer_size = n * 512;
75- if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size) < 512) {
76- /* The PRDs were too short. Reset the Active bit, but don't raise an
77- * interrupt. */
78+ prep_size = s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size);
79+ /* prepare_buf() must succeed and respect the limit */
80+ assert(prep_size >= 0 && prep_size <= n * 512);
81+
82+ /*
83+ * Now prep_size stores the number of bytes in the sglist, and
84+ * s->io_buffer_size stores the number of bytes described by the PRDs.
85+ */
86+
87+ if (prep_size < n * 512) {
88+ /*
89+ * The PRDs are too short for this request. Error condition!
90+ * Reset the Active bit and don't raise the interrupt.
91+ */
92 s->status = READY_STAT | SEEK_STAT;
93 dma_buf_commit(s, 0);
94 goto eot;