diff options
| author | Yogita Urade <yogita.urade@windriver.com> | 2024-12-04 05:23:35 +0000 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2024-12-09 07:54:03 -0800 |
| commit | 450857b441c79898168691082210dbd2cd81bfc1 (patch) | |
| tree | 9a7fcb257ab64c76dec6f9dd403dca5226e28662 | |
| parent | e0736e9b27fc54bc2c50b5e83ff0d66f4f067bd1 (diff) | |
| download | poky-450857b441c79898168691082210dbd2cd81bfc1.tar.gz | |
qemu: fix CVE-2024-3447
A heap-based buffer overflow was found in the SDHCI device
emulation of QEMU. The bug is triggered when both
`s->data_count` and the size of `s->fifo_buffer` are set to
0x200, leading to an out-of-bound access. A malicious guest
could use this flaw to crash the QEMU process on the host,
resulting in a denial of service condition.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2024-3447
Upstream patch:
https://gitlab.com/qemu-project/qemu/-/commit/2429cb7a9f460b544f4b07bcf02dbdedfc4dcb39
(From OE-Core rev: 01d7ac9244364b7f89cd2f99fff11c2417bcad03)
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2024-3447.patch | 137 |
2 files changed, 138 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index 16eb30e572..bee30cd56f 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
| @@ -127,6 +127,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
| 127 | file://CVE-2024-3446-0004.patch \ | 127 | file://CVE-2024-3446-0004.patch \ |
| 128 | file://CVE-2024-3446-0005.patch \ | 128 | file://CVE-2024-3446-0005.patch \ |
| 129 | file://CVE-2024-3446-0006.patch \ | 129 | file://CVE-2024-3446-0006.patch \ |
| 130 | file://CVE-2024-3447.patch \ | ||
| 130 | " | 131 | " |
| 131 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 132 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
| 132 | 133 | ||
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-3447.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-3447.patch new file mode 100644 index 0000000000..e403e3ec25 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-3447.patch | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | From 2429cb7a9f460b544f4b07bcf02dbdedfc4dcb39 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 3 | Date: Tue, 3 Dec 2024 08:19:23 +0000 | ||
| 4 | Subject: [PATCH] hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) | ||
| 5 | is set Per "SD Host Controller Standard Specification Version 3.00": | ||
| 6 | |||
| 7 | * 2.2.5 Transfer Mode Register (Offset 00Ch) | ||
| 8 | |||
| 9 | Writes to this register shall be ignored when the Command | ||
| 10 | Inhibit (DAT) in the Present State register is 1. | ||
| 11 | |||
| 12 | Do not update the TRNMOD register when Command Inhibit (DAT) | ||
| 13 | bit is set to avoid the present-status register going out of | ||
| 14 | sync, leading to malicious guest using DMA mode and overflowing | ||
| 15 | the FIFO buffer: | ||
| 16 | |||
| 17 | $ cat << EOF | qemu-system-i386 \ | ||
| 18 | -display none -nographic -nodefaults \ | ||
| 19 | -machine accel=qtest -m 512M \ | ||
| 20 | -device sdhci-pci,sd-spec-version=3 \ | ||
| 21 | -device sd-card,drive=mydrive \ | ||
| 22 | -drive if=none,index=0,file=null-co://,format=raw,id=mydrive \ | ||
| 23 | -qtest stdio | ||
| 24 | outl 0xcf8 0x80001013 | ||
| 25 | outl 0xcfc 0x91 | ||
| 26 | outl 0xcf8 0x80001001 | ||
| 27 | outl 0xcfc 0x06000000 | ||
| 28 | write 0x9100002c 0x1 0x05 | ||
| 29 | write 0x91000058 0x1 0x16 | ||
| 30 | write 0x91000005 0x1 0x04 | ||
| 31 | write 0x91000028 0x1 0x08 | ||
| 32 | write 0x16 0x1 0x21 | ||
| 33 | write 0x19 0x1 0x20 | ||
| 34 | write 0x9100000c 0x1 0x01 | ||
| 35 | write 0x9100000e 0x1 0x20 | ||
| 36 | write 0x9100000f 0x1 0x00 | ||
| 37 | write 0x9100000c 0x1 0x00 | ||
| 38 | write 0x91000020 0x1 0x00 | ||
| 39 | EOF | ||
| 40 | |||
| 41 | Stack trace (part): | ||
| 42 | ================================================================= | ||
| 43 | ==89993==ERROR: AddressSanitizer: heap-buffer-overflow on address | ||
| 44 | 0x615000029900 at pc 0x55d5f885700d bp 0x7ffc1e1e9470 sp 0x7ffc1e1e9468 | ||
| 45 | WRITE of size 1 at 0x615000029900 thread T0 | ||
| 46 | #0 0x55d5f885700c in sdhci_write_dataport hw/sd/sdhci.c:564:39 | ||
| 47 | #1 0x55d5f8849150 in sdhci_write hw/sd/sdhci.c:1223:13 | ||
| 48 | #2 0x55d5fa01db63 in memory_region_write_accessor system/memory.c:497:5 | ||
| 49 | #3 0x55d5fa01d245 in access_with_adjusted_size system/memory.c:573:18 | ||
| 50 | #4 0x55d5fa01b1a9 in memory_region_dispatch_write system/memory.c:1521:16 | ||
| 51 | #5 0x55d5fa09f5c9 in flatview_write_continue system/physmem.c:2711:23 | ||
| 52 | #6 0x55d5fa08f78b in flatview_write system/physmem.c:2753:12 | ||
| 53 | #7 0x55d5fa08f258 in address_space_write system/physmem.c:2860:18 | ||
| 54 | ... | ||
| 55 | 0x615000029900 is located 0 bytes to the right of 512-byte region | ||
| 56 | [0x615000029700,0x615000029900) allocated by thread T0 here: | ||
| 57 | #0 0x55d5f7237b27 in __interceptor_calloc | ||
| 58 | #1 0x7f9e36dd4c50 in g_malloc0 | ||
| 59 | #2 0x55d5f88672f7 in sdhci_pci_realize hw/sd/sdhci-pci.c:36:5 | ||
| 60 | #3 0x55d5f844b582 in pci_qdev_realize hw/pci/pci.c:2092:9 | ||
| 61 | #4 0x55d5fa2ee74b in device_set_realized hw/core/qdev.c:510:13 | ||
| 62 | #5 0x55d5fa325bfb in property_set_bool qom/object.c:2358:5 | ||
| 63 | #6 0x55d5fa31ea45 in object_property_set qom/object.c:1472:5 | ||
| 64 | #7 0x55d5fa332509 in object_property_set_qobject om/qom-qobject.c:28:10 | ||
| 65 | #8 0x55d5fa31f6ed in object_property_set_bool qom/object.c:1541:15 | ||
| 66 | #9 0x55d5fa2e2948 in qdev_realize hw/core/qdev.c:292:12 | ||
| 67 | #10 0x55d5f8eed3f1 in qdev_device_add_from_qdict system/qdev-monitor.c:719:10 | ||
| 68 | #11 0x55d5f8eef7ff in qdev_device_add system/qdev-monitor.c:738:11 | ||
| 69 | #12 0x55d5f8f211f0 in device_init_func system/vl.c:1200:11 | ||
| 70 | #13 0x55d5fad0877d in qemu_opts_foreach util/qemu-option.c:1135:14 | ||
| 71 | #14 0x55d5f8f0df9c in qemu_create_cli_devices system/vl.c:2638:5 | ||
| 72 | #15 0x55d5f8f0db24 in qmp_x_exit_preconfig system/vl.c:2706:5 | ||
| 73 | #16 0x55d5f8f14dc0 in qemu_init system/vl.c:3737:9 | ||
| 74 | ... | ||
| 75 | SUMMARY: AddressSanitizer: heap-buffer-overflow hw/sd/sdhci.c:564:39 | ||
| 76 | in sdhci_write_dataport | ||
| 77 | |||
| 78 | Add assertions to ensure the fifo_buffer[] is not overflowed by | ||
| 79 | malicious accesses to the Buffer Data Port register. | ||
| 80 | |||
| 81 | Fixes: CVE-2024-3447 | ||
| 82 | Cc: qemu-stable@nongnu.org | ||
| 83 | Fixes: d7dfca08 ("hw/sdhci: introduce standard SD host controller") | ||
| 84 | Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813 | ||
| 85 | |||
| 86 | Reported-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 87 | Reported-by: Chuhong Yuan <hslester96@gmail.com> | ||
| 88 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
| 89 | Message-Id: <CAFEAcA9iLiv1XGTGKeopgMa8Y9+8kvptvsb8z2OBeuy+5=NUfg@mail.gmail.com> | ||
| 90 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 91 | Message-Id: <20240409145524.27913-1-philmd@linaro.org> | ||
| 92 | (cherry picked from commit 9e4b27ca) | ||
| 93 | Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> | ||
| 94 | |||
| 95 | CVE: CVE-2024-3447 | ||
| 96 | Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/2429cb7a9f460b544f4b07bcf02dbdedfc4dcb39] | ||
| 97 | |||
| 98 | Signed-off-by: Yogita Urade <yogita.urade@windriver.com> | ||
| 99 | --- | ||
| 100 | hw/sd/sdhci.c | 8 ++++++++ | ||
| 101 | 1 file changed, 8 insertions(+) | ||
| 102 | |||
| 103 | diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c | ||
| 104 | index e0bbc9034..211daa4bb 100644 | ||
| 105 | --- a/hw/sd/sdhci.c | ||
| 106 | +++ b/hw/sd/sdhci.c | ||
| 107 | @@ -471,6 +471,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size) | ||
| 108 | } | ||
| 109 | |||
| 110 | for (i = 0; i < size; i++) { | ||
| 111 | + assert(s->data_count < s->buf_maxsz); | ||
| 112 | value |= s->fifo_buffer[s->data_count] << i * 8; | ||
| 113 | s->data_count++; | ||
| 114 | /* check if we've read all valid data (blksize bytes) from buffer */ | ||
| 115 | @@ -559,6 +560,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size) | ||
| 116 | } | ||
| 117 | |||
| 118 | for (i = 0; i < size; i++) { | ||
| 119 | + assert(s->data_count < s->buf_maxsz); | ||
| 120 | s->fifo_buffer[s->data_count] = value & 0xFF; | ||
| 121 | s->data_count++; | ||
| 122 | value >>= 8; | ||
| 123 | @@ -1184,6 +1186,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) | ||
| 124 | if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) { | ||
| 125 | value &= ~SDHC_TRNS_DMA; | ||
| 126 | } | ||
| 127 | + | ||
| 128 | + /* TRNMOD writes are inhibited while Command Inhibit (DAT) is true */ | ||
| 129 | + if (s->prnsts & SDHC_DATA_INHIBIT) { | ||
| 130 | + mask |= 0xffff; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK); | ||
| 134 | MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16); | ||
| 135 | |||
| 136 | -- | ||
| 137 | 2.40.0 | ||
