diff options
| author | Hitendra Prajapati <hprajapati@mvista.com> | 2022-10-10 19:30:53 +0530 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-10-27 16:54:43 +0100 |
| commit | e1f932366f081e80c6d61141161317b3a71b436a (patch) | |
| tree | 5fadb3d0c12d223fe1ba0ed965a0d03df5fb009b /meta/recipes-devtools | |
| parent | 17ecf62a19b63cb6c59db545b188b0e008fb93be (diff) | |
| download | poky-e1f932366f081e80c6d61141161317b3a71b436a.tar.gz | |
qemu: CVE-2021-3750 hcd-ehci: DMA reentrancy issue leads to use-after-free
Source: https://git.qemu.org/?p=qemu.git
MR: 117886
Type: Security Fix
Disposition: Backport from 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
ChangeID: 3af901d20ad8ff389468eda2c53b4943e3a77bb8
Description:
CVE-2021-3750 QEMU: hcd-ehci: DMA reentrancy issue leads to use-after-free.
(From OE-Core rev: 0f4b1db4fdc655e880ec66525eb7642978529e82)
Signed-off-by: Hitendra Prajapati <hprajapati@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')
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2021-3750.patch | 180 |
2 files changed, 181 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index 368be9979a..3c0b34d851 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
| @@ -111,6 +111,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
| 111 | file://CVE-2021-4207.patch \ | 111 | file://CVE-2021-4207.patch \ |
| 112 | file://CVE-2022-0216-1.patch \ | 112 | file://CVE-2022-0216-1.patch \ |
| 113 | file://CVE-2022-0216-2.patch \ | 113 | file://CVE-2022-0216-2.patch \ |
| 114 | file://CVE-2021-3750.patch \ | ||
| 114 | " | 115 | " |
| 115 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 116 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
| 116 | 117 | ||
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 | |||
