diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch b/meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch new file mode 100644 index 0000000000..43630e71fb --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch | |||
@@ -0,0 +1,180 @@ | |||
1 | From 1938fbc7ec197e2612ab2ce36dd69bff19208aa5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Hitendra Prajapati <hprajapati@mvista.com> | ||
3 | Date: Mon, 10 Oct 2022 17:44:41 +0530 | ||
4 | Subject: [PATCH] CVE-2021-3750 | ||
5 | |||
6 | Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=commit;h=b9d383ab797f54ae5fa8746117770709921dc529 && https://git.qemu.org/?p=qemu.git;a=commit;h=3ab6fdc91b72e156da22848f0003ff4225690ced && https://git.qemu.org/?p=qemu.git;a=commit;h=58e74682baf4e1ad26b064d8c02e5bc99c75c5d9] | ||
7 | CVE: CVE-2021-3750 | ||
8 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
9 | --- | ||
10 | exec.c | 55 +++++++++++++++++++++++++++++++------- | ||
11 | hw/intc/arm_gicv3_redist.c | 4 +-- | ||
12 | include/exec/memattrs.h | 9 +++++++ | ||
13 | 3 files changed, 56 insertions(+), 12 deletions(-) | ||
14 | |||
15 | diff --git a/exec.c b/exec.c | ||
16 | index 1360051a..10581d8d 100644 | ||
17 | --- a/exec.c | ||
18 | +++ b/exec.c | ||
19 | @@ -39,6 +39,7 @@ | ||
20 | #include "qemu/config-file.h" | ||
21 | #include "qemu/error-report.h" | ||
22 | #include "qemu/qemu-print.h" | ||
23 | +#include "qemu/log.h" | ||
24 | #if defined(CONFIG_USER_ONLY) | ||
25 | #include "qemu.h" | ||
26 | #else /* !CONFIG_USER_ONLY */ | ||
27 | @@ -3118,6 +3119,33 @@ static bool prepare_mmio_access(MemoryRegion *mr) | ||
28 | return release_lock; | ||
29 | } | ||
30 | |||
31 | +/** | ||
32 | ++ * flatview_access_allowed | ||
33 | ++ * @mr: #MemoryRegion to be accessed | ||
34 | ++ * @attrs: memory transaction attributes | ||
35 | ++ * @addr: address within that memory region | ||
36 | ++ * @len: the number of bytes to access | ||
37 | ++ * | ||
38 | ++ * Check if a memory transaction is allowed. | ||
39 | ++ * | ||
40 | ++ * Returns: true if transaction is allowed, false if denied. | ||
41 | ++ */ | ||
42 | +static bool flatview_access_allowed(MemoryRegion *mr, MemTxAttrs attrs, | ||
43 | + hwaddr addr, hwaddr len) | ||
44 | +{ | ||
45 | + if (likely(!attrs.memory)) { | ||
46 | + return true; | ||
47 | + } | ||
48 | + if (memory_region_is_ram(mr)) { | ||
49 | + return true; | ||
50 | + } | ||
51 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
52 | + "Invalid access to non-RAM device at " | ||
53 | + "addr 0x%" HWADDR_PRIX ", size %" HWADDR_PRIu ", " | ||
54 | + "region '%s'\n", addr, len, memory_region_name(mr)); | ||
55 | + return false; | ||
56 | +} | ||
57 | + | ||
58 | /* Called within RCU critical section. */ | ||
59 | static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, | ||
60 | MemTxAttrs attrs, | ||
61 | @@ -3131,7 +3159,10 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, | ||
62 | bool release_lock = false; | ||
63 | |||
64 | for (;;) { | ||
65 | - if (!memory_access_is_direct(mr, true)) { | ||
66 | + if (!flatview_access_allowed(mr, attrs, addr1, l)) { | ||
67 | + result |= MEMTX_ACCESS_ERROR; | ||
68 | + /* Keep going. */ | ||
69 | + } else if (!memory_access_is_direct(mr, true)) { | ||
70 | release_lock |= prepare_mmio_access(mr); | ||
71 | l = memory_access_size(mr, l, addr1); | ||
72 | /* XXX: could force current_cpu to NULL to avoid | ||
73 | @@ -3173,14 +3204,14 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, | ||
74 | hwaddr l; | ||
75 | hwaddr addr1; | ||
76 | MemoryRegion *mr; | ||
77 | - MemTxResult result = MEMTX_OK; | ||
78 | |||
79 | l = len; | ||
80 | mr = flatview_translate(fv, addr, &addr1, &l, true, attrs); | ||
81 | - result = flatview_write_continue(fv, addr, attrs, buf, len, | ||
82 | - addr1, l, mr); | ||
83 | - | ||
84 | - return result; | ||
85 | + if (!flatview_access_allowed(mr, attrs, addr, len)) { | ||
86 | + return MEMTX_ACCESS_ERROR; | ||
87 | + } | ||
88 | + return flatview_write_continue(fv, addr, attrs, buf, len, | ||
89 | + addr1, l, mr); | ||
90 | } | ||
91 | |||
92 | /* Called within RCU critical section. */ | ||
93 | @@ -3195,7 +3226,10 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, | ||
94 | bool release_lock = false; | ||
95 | |||
96 | for (;;) { | ||
97 | - if (!memory_access_is_direct(mr, false)) { | ||
98 | + if (!flatview_access_allowed(mr, attrs, addr1, l)) { | ||
99 | + result |= MEMTX_ACCESS_ERROR; | ||
100 | + /* Keep going. */ | ||
101 | + } else if (!memory_access_is_direct(mr, false)) { | ||
102 | /* I/O case */ | ||
103 | release_lock |= prepare_mmio_access(mr); | ||
104 | l = memory_access_size(mr, l, addr1); | ||
105 | @@ -3238,6 +3272,9 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, | ||
106 | |||
107 | l = len; | ||
108 | mr = flatview_translate(fv, addr, &addr1, &l, false, attrs); | ||
109 | + if (!flatview_access_allowed(mr, attrs, addr, len)) { | ||
110 | + return MEMTX_ACCESS_ERROR; | ||
111 | + } | ||
112 | return flatview_read_continue(fv, addr, attrs, buf, len, | ||
113 | addr1, l, mr); | ||
114 | } | ||
115 | @@ -3474,12 +3511,10 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, | ||
116 | MemTxAttrs attrs) | ||
117 | { | ||
118 | FlatView *fv; | ||
119 | - bool result; | ||
120 | |||
121 | RCU_READ_LOCK_GUARD(); | ||
122 | fv = address_space_to_flatview(as); | ||
123 | - result = flatview_access_valid(fv, addr, len, is_write, attrs); | ||
124 | - return result; | ||
125 | + return flatview_access_valid(fv, addr, len, is_write, attrs); | ||
126 | } | ||
127 | |||
128 | static hwaddr | ||
129 | diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c | ||
130 | index 8645220d..44368e28 100644 | ||
131 | --- a/hw/intc/arm_gicv3_redist.c | ||
132 | +++ b/hw/intc/arm_gicv3_redist.c | ||
133 | @@ -450,7 +450,7 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data, | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | - if (r == MEMTX_ERROR) { | ||
138 | + if (r != MEMTX_OK) { | ||
139 | qemu_log_mask(LOG_GUEST_ERROR, | ||
140 | "%s: invalid guest read at offset " TARGET_FMT_plx | ||
141 | "size %u\n", __func__, offset, size); | ||
142 | @@ -507,7 +507,7 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | - if (r == MEMTX_ERROR) { | ||
147 | + if (r != MEMTX_OK) { | ||
148 | qemu_log_mask(LOG_GUEST_ERROR, | ||
149 | "%s: invalid guest write at offset " TARGET_FMT_plx | ||
150 | "size %u\n", __func__, offset, size); | ||
151 | diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h | ||
152 | index 95f2d20d..9fb98bc1 100644 | ||
153 | --- a/include/exec/memattrs.h | ||
154 | +++ b/include/exec/memattrs.h | ||
155 | @@ -35,6 +35,14 @@ typedef struct MemTxAttrs { | ||
156 | unsigned int secure:1; | ||
157 | /* Memory access is usermode (unprivileged) */ | ||
158 | unsigned int user:1; | ||
159 | + /* | ||
160 | + * Bus interconnect and peripherals can access anything (memories, | ||
161 | + * devices) by default. By setting the 'memory' bit, bus transaction | ||
162 | + * are restricted to "normal" memories (per the AMBA documentation) | ||
163 | + * versus devices. Access to devices will be logged and rejected | ||
164 | + * (see MEMTX_ACCESS_ERROR). | ||
165 | + */ | ||
166 | + unsigned int memory:1; | ||
167 | /* Requester ID (for MSI for example) */ | ||
168 | unsigned int requester_id:16; | ||
169 | /* Invert endianness for this page */ | ||
170 | @@ -66,6 +74,7 @@ typedef struct MemTxAttrs { | ||
171 | #define MEMTX_OK 0 | ||
172 | #define MEMTX_ERROR (1U << 0) /* device returned an error */ | ||
173 | #define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */ | ||
174 | +#define MEMTX_ACCESS_ERROR (1U << 2) /* access denied */ | ||
175 | typedef uint32_t MemTxResult; | ||
176 | |||
177 | #endif | ||
178 | -- | ||
179 | 2.25.1 | ||
180 | |||