summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2021-09-15 17:04:16 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-09-30 00:02:22 +0100
commit81bb24c0f764fb371a2822649ef92bff208a82a0 (patch)
tree04e6d1d005f58428d7f196ac4628462382334f48 /meta/recipes-devtools/qemu
parent874fe76b00f7a8b31477417611df9929c21c1eaf (diff)
downloadpoky-81bb24c0f764fb371a2822649ef92bff208a82a0.tar.gz
qemu: Security fix CVE-2020-12829
Source: qemu.org MR: 105490 Type: Security Fix Disposition: Backport from https://git.qemu.org/?p=qemu.git;a=commit;h=b15a22bbcbe6a78dc3d88fe3134985e4cdd87de4 ChangeID: 6e222b766fc67c76cdc311d02cc47801992d0e66 Description: Affect qemu < 5.0.0 (From OE-Core rev: 7cd5c38b6d078c22519ad6b6e89caa9c1aa5ecd4) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/qemu')
-rw-r--r--meta/recipes-devtools/qemu/qemu.inc5
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-12829_1.patch164
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-12829_2.patch139
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-12829_3.patch47
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-12829_4.patch100
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2020-12829_5.patch266
6 files changed, 721 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index c8c170dda0..f5e8a9ae49 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -84,6 +84,11 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
84 file://CVE-2021-3582.patch \ 84 file://CVE-2021-3582.patch \
85 file://CVE-2021-3607.patch \ 85 file://CVE-2021-3607.patch \
86 file://CVE-2021-3608.patch \ 86 file://CVE-2021-3608.patch \
87 file://CVE-2020-12829_1.patch \
88 file://CVE-2020-12829_2.patch \
89 file://CVE-2020-12829_3.patch \
90 file://CVE-2020-12829_4.patch \
91 file://CVE-2020-12829_5.patch \
87 " 92 "
88UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" 93UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
89 94
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_1.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_1.patch
new file mode 100644
index 0000000000..6fee4f640d
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_1.patch
@@ -0,0 +1,164 @@
1From e29da77e5fddf6480e3a0e80b63d703edaec751b Mon Sep 17 00:00:00 2001
2From: BALATON Zoltan <balaton@eik.bme.hu>
3Date: Thu, 21 May 2020 21:39:44 +0200
4Subject: [PATCH] sm501: Convert printf + abort to qemu_log_mask
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Some places already use qemu_log_mask() to log unimplemented features
10or errors but some others have printf() then abort(). Convert these to
11qemu_log_mask() and avoid aborting to prevent guests to easily cause
12denial of service.
13
14Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
15Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16Message-id: 305af87f59d81e92f2aaff09eb8a3603b8baa322.1590089984.git.balaton@eik.bme.hu
17Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
18
19Upstream-Status: Backport
20CVE: CVE-2020-12829 dep#1
21Signed-off-by: Armin Kuster <akuster@mvista.com>
22
23---
24 hw/display/sm501.c | 57 ++++++++++++++++++++++------------------------
25 1 file changed, 27 insertions(+), 30 deletions(-)
26
27diff --git a/hw/display/sm501.c b/hw/display/sm501.c
28index acc692531a..bd3ccfe311 100644
29--- a/hw/display/sm501.c
30+++ b/hw/display/sm501.c
31@@ -727,8 +727,8 @@ static void sm501_2d_operation(SM501State *s)
32 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
33
34 if (addressing != 0x0) {
35- printf("%s: only XY addressing is supported.\n", __func__);
36- abort();
37+ qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
38+ return;
39 }
40
41 if (rop_mode == 0) {
42@@ -754,8 +754,8 @@ static void sm501_2d_operation(SM501State *s)
43
44 if ((s->twoD_source_base & 0x08000000) ||
45 (s->twoD_destination_base & 0x08000000)) {
46- printf("%s: only local memory is supported.\n", __func__);
47- abort();
48+ qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n");
49+ return;
50 }
51
52 switch (operation) {
53@@ -823,9 +823,9 @@ static void sm501_2d_operation(SM501State *s)
54 break;
55
56 default:
57- printf("non-implemented SM501 2D operation. %d\n", operation);
58- abort();
59- break;
60+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n",
61+ operation);
62+ return;
63 }
64
65 if (dst_base >= get_fb_addr(s, crt) &&
66@@ -892,9 +892,8 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
67 break;
68
69 default:
70- printf("sm501 system config : not implemented register read."
71- " addr=%x\n", (int)addr);
72- abort();
73+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config"
74+ "register read. addr=%" HWADDR_PRIx "\n", addr);
75 }
76
77 return ret;
78@@ -948,15 +947,15 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
79 break;
80 case SM501_ENDIAN_CONTROL:
81 if (value & 0x00000001) {
82- printf("sm501 system config : big endian mode not implemented.\n");
83- abort();
84+ qemu_log_mask(LOG_UNIMP, "sm501: system config big endian mode not"
85+ " implemented.\n");
86 }
87 break;
88
89 default:
90- printf("sm501 system config : not implemented register write."
91- " addr=%x, val=%x\n", (int)addr, (uint32_t)value);
92- abort();
93+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config"
94+ "register write. addr=%" HWADDR_PRIx
95+ ", val=%" PRIx64 "\n", addr, value);
96 }
97 }
98
99@@ -1207,9 +1206,8 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
100 break;
101
102 default:
103- printf("sm501 disp ctrl : not implemented register read."
104- " addr=%x\n", (int)addr);
105- abort();
106+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
107+ "read. addr=%" HWADDR_PRIx "\n", addr);
108 }
109
110 return ret;
111@@ -1345,9 +1343,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr,
112 break;
113
114 default:
115- printf("sm501 disp ctrl : not implemented register write."
116- " addr=%x, val=%x\n", (int)addr, (unsigned)value);
117- abort();
118+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
119+ "write. addr=%" HWADDR_PRIx
120+ ", val=%" PRIx64 "\n", addr, value);
121 }
122 }
123
124@@ -1433,9 +1431,8 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
125 ret = 0; /* Should return interrupt status */
126 break;
127 default:
128- printf("sm501 disp ctrl : not implemented register read."
129- " addr=%x\n", (int)addr);
130- abort();
131+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
132+ "read. addr=%" HWADDR_PRIx "\n", addr);
133 }
134
135 return ret;
136@@ -1520,9 +1517,9 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr,
137 /* ignored, writing 0 should clear interrupt status */
138 break;
139 default:
140- printf("sm501 2d engine : not implemented register write."
141- " addr=%x, val=%x\n", (int)addr, (unsigned)value);
142- abort();
143+ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2d engine register "
144+ "write. addr=%" HWADDR_PRIx
145+ ", val=%" PRIx64 "\n", addr, value);
146 }
147 }
148
149@@ -1670,9 +1667,9 @@ static void sm501_update_display(void *opaque)
150 draw_line = draw_line32_funcs[dst_depth_index];
151 break;
152 default:
153- printf("sm501 update display : invalid control register value.\n");
154- abort();
155- break;
156+ qemu_log_mask(LOG_GUEST_ERROR, "sm501: update display"
157+ "invalid control register value.\n");
158+ return;
159 }
160
161 /* set up to draw hardware cursor */
162--
1632.25.1
164
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_2.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_2.patch
new file mode 100644
index 0000000000..e7258a43d3
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_2.patch
@@ -0,0 +1,139 @@
1From 6f8183b5dc5b309378687830a25e85ea8fb860ea Mon Sep 17 00:00:00 2001
2From: BALATON Zoltan <balaton@eik.bme.hu>
3Date: Thu, 21 May 2020 21:39:44 +0200
4Subject: [PATCH 2/5] sm501: Shorten long variable names in sm501_2d_operation
5
6This increases readability and cleans up some confusing naming.
7
8Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
9Message-id: b9b67b94c46e945252a73c77dfd117132c63c4fb.1590089984.git.balaton@eik.bme.hu
10Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
11
12Upstream-Status: Backport
13CVE: CVE-2020-12829 dep#2
14Signed-off-by: Armin Kuster <akuster@mvista.com>
15
16---
17 hw/display/sm501.c | 45 ++++++++++++++++++++++-----------------------
18 1 file changed, 22 insertions(+), 23 deletions(-)
19
20diff --git a/hw/display/sm501.c b/hw/display/sm501.c
21index bd3ccfe311..f42d05e1e4 100644
22--- a/hw/display/sm501.c
23+++ b/hw/display/sm501.c
24@@ -700,17 +700,16 @@ static inline void hwc_invalidate(SM501State *s, int crt)
25 static void sm501_2d_operation(SM501State *s)
26 {
27 /* obtain operation parameters */
28- int operation = (s->twoD_control >> 16) & 0x1f;
29+ int cmd = (s->twoD_control >> 16) & 0x1F;
30 int rtl = s->twoD_control & 0x8000000;
31 int src_x = (s->twoD_source >> 16) & 0x01FFF;
32 int src_y = s->twoD_source & 0xFFFF;
33 int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
34 int dst_y = s->twoD_destination & 0xFFFF;
35- int operation_width = (s->twoD_dimension >> 16) & 0x1FFF;
36- int operation_height = s->twoD_dimension & 0xFFFF;
37+ int width = (s->twoD_dimension >> 16) & 0x1FFF;
38+ int height = s->twoD_dimension & 0xFFFF;
39 uint32_t color = s->twoD_foreground;
40- int format_flags = (s->twoD_stretch >> 20) & 0x3;
41- int addressing = (s->twoD_stretch >> 16) & 0xF;
42+ int format = (s->twoD_stretch >> 20) & 0x3;
43 int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */
44 /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */
45 int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1;
46@@ -721,12 +720,12 @@ static void sm501_2d_operation(SM501State *s)
47 /* get frame buffer info */
48 uint8_t *src = s->local_mem + src_base;
49 uint8_t *dst = s->local_mem + dst_base;
50- int src_width = s->twoD_pitch & 0x1FFF;
51- int dst_width = (s->twoD_pitch >> 16) & 0x1FFF;
52+ int src_pitch = s->twoD_pitch & 0x1FFF;
53+ int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
54 int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
55 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
56
57- if (addressing != 0x0) {
58+ if ((s->twoD_stretch >> 16) & 0xF) {
59 qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
60 return;
61 }
62@@ -758,20 +757,20 @@ static void sm501_2d_operation(SM501State *s)
63 return;
64 }
65
66- switch (operation) {
67+ switch (cmd) {
68 case 0x00: /* copy area */
69 #define COPY_AREA(_bpp, _pixel_type, rtl) { \
70 int y, x, index_d, index_s; \
71- for (y = 0; y < operation_height; y++) { \
72- for (x = 0; x < operation_width; x++) { \
73+ for (y = 0; y < height; y++) { \
74+ for (x = 0; x < width; x++) { \
75 _pixel_type val; \
76 \
77 if (rtl) { \
78- index_s = ((src_y - y) * src_width + src_x - x) * _bpp; \
79- index_d = ((dst_y - y) * dst_width + dst_x - x) * _bpp; \
80+ index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \
81+ index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \
82 } else { \
83- index_s = ((src_y + y) * src_width + src_x + x) * _bpp; \
84- index_d = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \
85+ index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \
86+ index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \
87 } \
88 if (rop_mode == 1 && rop == 5) { \
89 /* Invert dest */ \
90@@ -783,7 +782,7 @@ static void sm501_2d_operation(SM501State *s)
91 } \
92 } \
93 }
94- switch (format_flags) {
95+ switch (format) {
96 case 0:
97 COPY_AREA(1, uint8_t, rtl);
98 break;
99@@ -799,15 +798,15 @@ static void sm501_2d_operation(SM501State *s)
100 case 0x01: /* fill rectangle */
101 #define FILL_RECT(_bpp, _pixel_type) { \
102 int y, x; \
103- for (y = 0; y < operation_height; y++) { \
104- for (x = 0; x < operation_width; x++) { \
105- int index = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \
106+ for (y = 0; y < height; y++) { \
107+ for (x = 0; x < width; x++) { \
108+ int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \
109 *(_pixel_type *)&dst[index] = (_pixel_type)color; \
110 } \
111 } \
112 }
113
114- switch (format_flags) {
115+ switch (format) {
116 case 0:
117 FILL_RECT(1, uint8_t);
118 break;
119@@ -824,14 +823,14 @@ static void sm501_2d_operation(SM501State *s)
120
121 default:
122 qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n",
123- operation);
124+ cmd);
125 return;
126 }
127
128 if (dst_base >= get_fb_addr(s, crt) &&
129 dst_base <= get_fb_addr(s, crt) + fb_len) {
130- int dst_len = MIN(fb_len, ((dst_y + operation_height - 1) * dst_width +
131- dst_x + operation_width) * (1 << format_flags));
132+ int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch +
133+ dst_x + width) * (1 << format));
134 if (dst_len) {
135 memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len);
136 }
137--
1382.25.1
139
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_3.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_3.patch
new file mode 100644
index 0000000000..c647028cfe
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_3.patch
@@ -0,0 +1,47 @@
1From 2824809b7f8f03ddc6e2b7e33e78c06022424298 Mon Sep 17 00:00:00 2001
2From: BALATON Zoltan <balaton@eik.bme.hu>
3Date: Thu, 21 May 2020 21:39:44 +0200
4Subject: [PATCH 3/5] sm501: Use BIT(x) macro to shorten constant
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
10Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11Message-id: 124bf5de8d7cf503b32b377d0445029a76bfbd49.1590089984.git.balaton@eik.bme.hu
12Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
13
14Upstream-Status: Backport
15CVE: CVE-2020-12829 dep#3
16Signed-off-by: Armin Kuster <akuster@mvista.com>
17
18---
19 hw/display/sm501.c | 5 ++---
20 1 file changed, 2 insertions(+), 3 deletions(-)
21
22diff --git a/hw/display/sm501.c b/hw/display/sm501.c
23index f42d05e1e4..97660090bb 100644
24--- a/hw/display/sm501.c
25+++ b/hw/display/sm501.c
26@@ -701,7 +701,7 @@ static void sm501_2d_operation(SM501State *s)
27 {
28 /* obtain operation parameters */
29 int cmd = (s->twoD_control >> 16) & 0x1F;
30- int rtl = s->twoD_control & 0x8000000;
31+ int rtl = s->twoD_control & BIT(27);
32 int src_x = (s->twoD_source >> 16) & 0x01FFF;
33 int src_y = s->twoD_source & 0xFFFF;
34 int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
35@@ -751,8 +751,7 @@ static void sm501_2d_operation(SM501State *s)
36 }
37 }
38
39- if ((s->twoD_source_base & 0x08000000) ||
40- (s->twoD_destination_base & 0x08000000)) {
41+ if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) {
42 qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n");
43 return;
44 }
45--
462.25.1
47
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_4.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_4.patch
new file mode 100644
index 0000000000..485af05e1e
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_4.patch
@@ -0,0 +1,100 @@
1From 3d0b096298b5579a7fa0753ad90968b27bc65372 Mon Sep 17 00:00:00 2001
2From: BALATON Zoltan <balaton@eik.bme.hu>
3Date: Thu, 21 May 2020 21:39:44 +0200
4Subject: [PATCH 4/5] sm501: Clean up local variables in sm501_2d_operation
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Make variables local to the block they are used in to make it clearer
10which operation they are needed for.
11
12Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
13Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14Message-id: ae59f8138afe7f6a5a4a82539d0f61496a906b06.1590089984.git.balaton@eik.bme.hu
15Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
16
17Upstream-Status: Backport
18CVE: CVE-2020-12829 dep#4
19Signed-off-by: Armin Kuster <akuster@mvista.com>
20
21---
22 hw/display/sm501.c | 31 ++++++++++++++++---------------
23 1 file changed, 16 insertions(+), 15 deletions(-)
24
25diff --git a/hw/display/sm501.c b/hw/display/sm501.c
26index 97660090bb..5ed57703d8 100644
27--- a/hw/display/sm501.c
28+++ b/hw/display/sm501.c
29@@ -699,28 +699,19 @@ static inline void hwc_invalidate(SM501State *s, int crt)
30
31 static void sm501_2d_operation(SM501State *s)
32 {
33- /* obtain operation parameters */
34 int cmd = (s->twoD_control >> 16) & 0x1F;
35 int rtl = s->twoD_control & BIT(27);
36- int src_x = (s->twoD_source >> 16) & 0x01FFF;
37- int src_y = s->twoD_source & 0xFFFF;
38- int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
39- int dst_y = s->twoD_destination & 0xFFFF;
40- int width = (s->twoD_dimension >> 16) & 0x1FFF;
41- int height = s->twoD_dimension & 0xFFFF;
42- uint32_t color = s->twoD_foreground;
43 int format = (s->twoD_stretch >> 20) & 0x3;
44 int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */
45 /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */
46 int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1;
47 int rop = s->twoD_control & 0xFF;
48- uint32_t src_base = s->twoD_source_base & 0x03FFFFFF;
49+ int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
50+ int dst_y = s->twoD_destination & 0xFFFF;
51+ int width = (s->twoD_dimension >> 16) & 0x1FFF;
52+ int height = s->twoD_dimension & 0xFFFF;
53 uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF;
54-
55- /* get frame buffer info */
56- uint8_t *src = s->local_mem + src_base;
57 uint8_t *dst = s->local_mem + dst_base;
58- int src_pitch = s->twoD_pitch & 0x1FFF;
59 int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
60 int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
61 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
62@@ -758,6 +749,13 @@ static void sm501_2d_operation(SM501State *s)
63
64 switch (cmd) {
65 case 0x00: /* copy area */
66+ {
67+ int src_x = (s->twoD_source >> 16) & 0x01FFF;
68+ int src_y = s->twoD_source & 0xFFFF;
69+ uint32_t src_base = s->twoD_source_base & 0x03FFFFFF;
70+ uint8_t *src = s->local_mem + src_base;
71+ int src_pitch = s->twoD_pitch & 0x1FFF;
72+
73 #define COPY_AREA(_bpp, _pixel_type, rtl) { \
74 int y, x, index_d, index_s; \
75 for (y = 0; y < height; y++) { \
76@@ -793,8 +791,11 @@ static void sm501_2d_operation(SM501State *s)
77 break;
78 }
79 break;
80-
81+ }
82 case 0x01: /* fill rectangle */
83+ {
84+ uint32_t color = s->twoD_foreground;
85+
86 #define FILL_RECT(_bpp, _pixel_type) { \
87 int y, x; \
88 for (y = 0; y < height; y++) { \
89@@ -819,7 +820,7 @@ static void sm501_2d_operation(SM501State *s)
90 break;
91 }
92 break;
93-
94+ }
95 default:
96 qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n",
97 cmd);
98--
992.25.1
100
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_5.patch b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_5.patch
new file mode 100644
index 0000000000..ab09e8b039
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2020-12829_5.patch
@@ -0,0 +1,266 @@
1From b15a22bbcbe6a78dc3d88fe3134985e4cdd87de4 Mon Sep 17 00:00:00 2001
2From: BALATON Zoltan <balaton@eik.bme.hu>
3Date: Thu, 21 May 2020 21:39:44 +0200
4Subject: [PATCH 5/5] sm501: Replace hand written implementation with pixman
5 where possible
6
7Besides being faster this should also prevent malicious guests to
8abuse 2D engine to overwrite data or cause a crash.
9
10Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
11Message-id: 58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu
12Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
13
14Upstream-Status: Backport
15CVE: CVE-2020-12829
16Signed-off-by: Armin Kuster <akuster@mvista.com>
17
18---
19 hw/display/sm501.c | 207 ++++++++++++++++++++++++++-------------------
20 1 file changed, 119 insertions(+), 88 deletions(-)
21
22diff --git a/hw/display/sm501.c b/hw/display/sm501.c
23index 5ed57703d8..8bf4d111f4 100644
24--- a/hw/display/sm501.c
25+++ b/hw/display/sm501.c
26@@ -706,13 +706,12 @@ static void sm501_2d_operation(SM501State *s)
27 /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */
28 int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1;
29 int rop = s->twoD_control & 0xFF;
30- int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
31- int dst_y = s->twoD_destination & 0xFFFF;
32- int width = (s->twoD_dimension >> 16) & 0x1FFF;
33- int height = s->twoD_dimension & 0xFFFF;
34+ unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
35+ unsigned int dst_y = s->twoD_destination & 0xFFFF;
36+ unsigned int width = (s->twoD_dimension >> 16) & 0x1FFF;
37+ unsigned int height = s->twoD_dimension & 0xFFFF;
38 uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF;
39- uint8_t *dst = s->local_mem + dst_base;
40- int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
41+ unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
42 int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
43 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
44
45@@ -721,104 +720,136 @@ static void sm501_2d_operation(SM501State *s)
46 return;
47 }
48
49- if (rop_mode == 0) {
50- if (rop != 0xcc) {
51- /* Anything other than plain copies are not supported */
52- qemu_log_mask(LOG_UNIMP, "sm501: rop3 mode with rop %x is not "
53- "supported.\n", rop);
54- }
55- } else {
56- if (rop2_source_is_pattern && rop != 0x5) {
57- /* For pattern source, we support only inverse dest */
58- qemu_log_mask(LOG_UNIMP, "sm501: rop2 source being the pattern and "
59- "rop %x is not supported.\n", rop);
60- } else {
61- if (rop != 0x5 && rop != 0xc) {
62- /* Anything other than plain copies or inverse dest is not
63- * supported */
64- qemu_log_mask(LOG_UNIMP, "sm501: rop mode %x is not "
65- "supported.\n", rop);
66- }
67- }
68- }
69-
70 if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) {
71 qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n");
72 return;
73 }
74
75+ if (!dst_pitch) {
76+ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero dest pitch.\n");
77+ return;
78+ }
79+
80+ if (!width || !height) {
81+ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero size 2D op.\n");
82+ return;
83+ }
84+
85+ if (rtl) {
86+ dst_x -= width - 1;
87+ dst_y -= height - 1;
88+ }
89+
90+ if (dst_base >= get_local_mem_size(s) || dst_base +
91+ (dst_x + width + (dst_y + height) * (dst_pitch + width)) *
92+ (1 << format) >= get_local_mem_size(s)) {
93+ qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n");
94+ return;
95+ }
96+
97 switch (cmd) {
98- case 0x00: /* copy area */
99+ case 0: /* BitBlt */
100 {
101- int src_x = (s->twoD_source >> 16) & 0x01FFF;
102- int src_y = s->twoD_source & 0xFFFF;
103+ unsigned int src_x = (s->twoD_source >> 16) & 0x01FFF;
104+ unsigned int src_y = s->twoD_source & 0xFFFF;
105 uint32_t src_base = s->twoD_source_base & 0x03FFFFFF;
106- uint8_t *src = s->local_mem + src_base;
107- int src_pitch = s->twoD_pitch & 0x1FFF;
108-
109-#define COPY_AREA(_bpp, _pixel_type, rtl) { \
110- int y, x, index_d, index_s; \
111- for (y = 0; y < height; y++) { \
112- for (x = 0; x < width; x++) { \
113- _pixel_type val; \
114- \
115- if (rtl) { \
116- index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \
117- index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \
118- } else { \
119- index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \
120- index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \
121- } \
122- if (rop_mode == 1 && rop == 5) { \
123- /* Invert dest */ \
124- val = ~*(_pixel_type *)&dst[index_d]; \
125- } else { \
126- val = *(_pixel_type *)&src[index_s]; \
127- } \
128- *(_pixel_type *)&dst[index_d] = val; \
129- } \
130- } \
131- }
132- switch (format) {
133- case 0:
134- COPY_AREA(1, uint8_t, rtl);
135- break;
136- case 1:
137- COPY_AREA(2, uint16_t, rtl);
138- break;
139- case 2:
140- COPY_AREA(4, uint32_t, rtl);
141- break;
142+ unsigned int src_pitch = s->twoD_pitch & 0x1FFF;
143+
144+ if (!src_pitch) {
145+ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero src pitch.\n");
146+ return;
147+ }
148+
149+ if (rtl) {
150+ src_x -= width - 1;
151+ src_y -= height - 1;
152+ }
153+
154+ if (src_base >= get_local_mem_size(s) || src_base +
155+ (src_x + width + (src_y + height) * (src_pitch + width)) *
156+ (1 << format) >= get_local_mem_size(s)) {
157+ qemu_log_mask(LOG_GUEST_ERROR,
158+ "sm501: 2D op src is outside vram.\n");
159+ return;
160+ }
161+
162+ if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) {
163+ /* Invert dest, is there a way to do this with pixman? */
164+ unsigned int x, y, i;
165+ uint8_t *d = s->local_mem + dst_base;
166+
167+ for (y = 0; y < height; y++) {
168+ i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format);
169+ for (x = 0; x < width; x++, i += (1 << format)) {
170+ switch (format) {
171+ case 0:
172+ d[i] = ~d[i];
173+ break;
174+ case 1:
175+ *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i];
176+ break;
177+ case 2:
178+ *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i];
179+ break;
180+ }
181+ }
182+ }
183+ } else {
184+ /* Do copy src for unimplemented ops, better than unpainted area */
185+ if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) ||
186+ (!rop_mode && rop != 0xcc)) {
187+ qemu_log_mask(LOG_UNIMP,
188+ "sm501: rop%d op %x%s not implemented\n",
189+ (rop_mode ? 2 : 3), rop,
190+ (rop2_source_is_pattern ?
191+ " with pattern source" : ""));
192+ }
193+ /* Check for overlaps, this could be made more exact */
194+ uint32_t sb, se, db, de;
195+ sb = src_base + src_x + src_y * (width + src_pitch);
196+ se = sb + width + height * (width + src_pitch);
197+ db = dst_base + dst_x + dst_y * (width + dst_pitch);
198+ de = db + width + height * (width + dst_pitch);
199+ if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) {
200+ /* regions may overlap: copy via temporary */
201+ int llb = width * (1 << format);
202+ int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
203+ uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) *
204+ height);
205+ pixman_blt((uint32_t *)&s->local_mem[src_base], tmp,
206+ src_pitch * (1 << format) / sizeof(uint32_t),
207+ tmp_stride, 8 * (1 << format), 8 * (1 << format),
208+ src_x, src_y, 0, 0, width, height);
209+ pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base],
210+ tmp_stride,
211+ dst_pitch * (1 << format) / sizeof(uint32_t),
212+ 8 * (1 << format), 8 * (1 << format),
213+ 0, 0, dst_x, dst_y, width, height);
214+ g_free(tmp);
215+ } else {
216+ pixman_blt((uint32_t *)&s->local_mem[src_base],
217+ (uint32_t *)&s->local_mem[dst_base],
218+ src_pitch * (1 << format) / sizeof(uint32_t),
219+ dst_pitch * (1 << format) / sizeof(uint32_t),
220+ 8 * (1 << format), 8 * (1 << format),
221+ src_x, src_y, dst_x, dst_y, width, height);
222+ }
223 }
224 break;
225 }
226- case 0x01: /* fill rectangle */
227+ case 1: /* Rectangle Fill */
228 {
229 uint32_t color = s->twoD_foreground;
230
231-#define FILL_RECT(_bpp, _pixel_type) { \
232- int y, x; \
233- for (y = 0; y < height; y++) { \
234- for (x = 0; x < width; x++) { \
235- int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \
236- *(_pixel_type *)&dst[index] = (_pixel_type)color; \
237- } \
238- } \
239- }
240-
241- switch (format) {
242- case 0:
243- FILL_RECT(1, uint8_t);
244- break;
245- case 1:
246- color = cpu_to_le16(color);
247- FILL_RECT(2, uint16_t);
248- break;
249- case 2:
250+ if (format == 2) {
251 color = cpu_to_le32(color);
252- FILL_RECT(4, uint32_t);
253- break;
254+ } else if (format == 1) {
255+ color = cpu_to_le16(color);
256 }
257+
258+ pixman_fill((uint32_t *)&s->local_mem[dst_base],
259+ dst_pitch * (1 << format) / sizeof(uint32_t),
260+ 8 * (1 << format), dst_x, dst_y, width, height, color);
261 break;
262 }
263 default:
264--
2652.25.1
266