xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/qemu/qemu/CVE-2021-3750-3.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From 3ab6fdc91b72e156da22848f0003ff4225690ced Mon Sep 17 00:00:00 2001
2From: =?utf8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
3Date: Wed, 15 Dec 2021 19:24:21 +0100
4Subject: [PATCH] softmmu/physmem: Introduce MemTxAttrs::memory field and
5 MEMTX_ACCESS_ERROR
6MIME-Version: 1.0
7Content-Type: text/plain; charset=utf8
8Content-Transfer-Encoding: 8bit
9
10Add the 'memory' bit to the memory attributes to restrict bus
11controller accesses to memories.
12
13Introduce flatview_access_allowed() to check bus permission
14before running any bus transaction.
15
16Have read/write accessors return MEMTX_ACCESS_ERROR if an access is
17restricted.
18
19There is no change for the default case where 'memory' is not set.
20
21Signed-off-by: Philippe Mathieu-DaudÃf© <philmd@redhat.com>
22Message-Id: <20211215182421.418374-4-philmd@redhat.com>
23Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
25[thuth: Replaced MEMTX_BUS_ERROR with MEMTX_ACCESS_ERROR, remove "inline"]
26Signed-off-by: Thomas Huth <thuth@redhat.com>
27Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com>
28
29CVE: CVE-2021-3750
30
31Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=commit;h=3ab6fdc91b72e156da22848f0003ff4225690ced]
32---
33 include/exec/memattrs.h |  9 +++++++++
34 softmmu/physmem.c       | 44 ++++++++++++++++++++++++++++++++++++++++++--
35 2 files changed, 51 insertions(+), 2 deletions(-)
36
37diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
38index 95f2d20..9fb98bc 100644
39--- a/include/exec/memattrs.h
40+++ b/include/exec/memattrs.h
41@@ -35,6 +35,14 @@ typedef struct MemTxAttrs {
42     unsigned int secure:1;
43     /* Memory access is usermode (unprivileged) */
44     unsigned int user:1;
45+    /*
46+     * Bus interconnect and peripherals can access anything (memories,
47+     * devices) by default. By setting the 'memory' bit, bus transaction
48+     * are restricted to "normal" memories (per the AMBA documentation)
49+     * versus devices. Access to devices will be logged and rejected
50+     * (see MEMTX_ACCESS_ERROR).
51+     */
52+    unsigned int memory:1;
53     /* Requester ID (for MSI for example) */
54     unsigned int requester_id:16;
55     /* Invert endianness for this page */
56@@ -66,6 +74,7 @@ typedef struct MemTxAttrs {
57 #define MEMTX_OK 0
58 #define MEMTX_ERROR             (1U << 0) /* device returned an error */
59 #define MEMTX_DECODE_ERROR      (1U << 1) /* nothing at that address */
60+#define MEMTX_ACCESS_ERROR      (1U << 2) /* access denied */
61 typedef uint32_t MemTxResult;
62
63 #endif
64diff --git a/softmmu/physmem.c b/softmmu/physmem.c
65index 3d968ca..4e1b27a 100644
66--- a/softmmu/physmem.c
67+++ b/softmmu/physmem.c
68@@ -41,6 +41,7 @@
69 #include "qemu/config-file.h"
70 #include "qemu/error-report.h"
71 #include "qemu/qemu-print.h"
72+#include "qemu/log.h"
73 #include "exec/memory.h"
74 #include "exec/ioport.h"
75 #include "sysemu/dma.h"
76@@ -2759,6 +2760,33 @@ static bool prepare_mmio_access(MemoryRe
77     return release_lock;
78 }
79
80+/**
81+ * flatview_access_allowed
82+ * @mr: #MemoryRegion to be accessed
83+ * @attrs: memory transaction attributes
84+ * @addr: address within that memory region
85+ * @len: the number of bytes to access
86+ *
87+ * Check if a memory transaction is allowed.
88+ *
89+ * Returns: true if transaction is allowed, false if denied.
90+ */
91+static bool flatview_access_allowed(MemoryRegion *mr, MemTxAttrs attrs,
92+                                    hwaddr addr, hwaddr len)
93+{
94+    if (likely(!attrs.memory)) {
95+        return true;
96+    }
97+    if (memory_region_is_ram(mr)) {
98+        return true;
99+    }
100+    qemu_log_mask(LOG_GUEST_ERROR,
101+                  "Invalid access to non-RAM device at "
102+                  "addr 0x%" HWADDR_PRIX ", size %" HWADDR_PRIu ", "
103+                  "region '%s'\n", addr, len, memory_region_name(mr));
104+    return false;
105+}
106+
107 /* Called within RCU critical section.  */
108 static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
109                                            MemTxAttrs attrs,
110@@ -2773,7 +2801,10 @@ static MemTxResult flatview_write_contin
111     const uint8_t *buf = ptr;
112
113     for (;;) {
114-        if (!memory_access_is_direct(mr, true)) {
115+        if (!flatview_access_allowed(mr, attrs, addr1, l)) {
116+            result |= MEMTX_ACCESS_ERROR;
117+            /* Keep going. */
118+        } else if (!memory_access_is_direct(mr, true)) {
119             release_lock |= prepare_mmio_access(mr);
120             l = memory_access_size(mr, l, addr1);
121             /* XXX: could force current_cpu to NULL to avoid
122@@ -2818,6 +2849,9 @@ static MemTxResult flatview_write(FlatVi
123
124     l = len;
125     mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
126+    if (!flatview_access_allowed(mr, attrs, addr, len)) {
127+        return MEMTX_ACCESS_ERROR;
128+    }
129     return flatview_write_continue(fv, addr, attrs, buf, len,
130                                    addr1, l, mr);
131 }
132@@ -2836,7 +2870,10 @@ MemTxResult flatview_read_continue(FlatV
133
134     fuzz_dma_read_cb(addr, len, mr);
135     for (;;) {
136-        if (!memory_access_is_direct(mr, false)) {
137+        if (!flatview_access_allowed(mr, attrs, addr1, l)) {
138+            result |= MEMTX_ACCESS_ERROR;
139+            /* Keep going. */
140+        } else if (!memory_access_is_direct(mr, false)) {
141             /* I/O case */
142             release_lock |= prepare_mmio_access(mr);
143             l = memory_access_size(mr, l, addr1);
144@@ -2879,6 +2916,9 @@ static MemTxResult flatview_read(FlatVie
145
146     l = len;
147     mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
148+    if (!flatview_access_allowed(mr, attrs, addr, len)) {
149+        return MEMTX_ACCESS_ERROR;
150+    }
151     return flatview_read_continue(fv, addr, attrs, buf, len,
152                                   addr1, l, mr);
153 }
154--
1551.8.3.1
156
157