summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPoonam Jadhav <ppjadhav456@gmail.com>2024-03-01 11:44:51 +0530
committerSteve Sakoman <steve@sakoman.com>2024-03-07 08:32:54 -1000
commit84598dca804c7b21a3bbde1271cb7e8d7dd67eec (patch)
treea2e9efb81cd8391c0e3a88d6e8dca4f52b787bf7
parent3c091d5d049f9970f38e368a041cf5d24046ea4b (diff)
downloadpoky-84598dca804c7b21a3bbde1271cb7e8d7dd67eec.tar.gz
qemu: Fix CVE-2023-42467
1. scsi-disk: allow MODE SELECT block descriptor to set the block size Link: https://github.com/qemu/qemu/commit/356c4c441ec01910314c5867c680bef80d1dd373 The MODE SELECT command can contain an optional block descriptor that can be used to set the device block size. If the block descriptor is present then update the block size on the SCSI device accordingly. This allows CDROMs to be used with A/UX which requires a CDROM drive which is capable of switching from a 2048 byte sector size to a 512 byte sector size. 2. scsi-disk: ensure block size is non-zero and changes limited to bits 8-15 Link: https://github.com/qemu/qemu/commit/55794c904df723109b228da28b5db778e0df3110 The existing code assumes that the block size can be generated from p[1] << 8 in multiple places which ignores the top and bottom 8 bits. If the block size is allowed to be set to an arbitrary value then this causes a mismatch between the value written by the guest in the block descriptor and the value subsequently read back using READ CAPACITY causing the guest to generate requests that can crash QEMU. For now restrict block size changes to bits 8-15 and also ignore requests to set the block size to 0 which causes the SCSI emulation to crash in at least one place with a divide by zero error. 3. Disallow block sizes smaller than 512 [CVE-2023-42467] Link: https://gitlab.com/qemu-project/qemu/-/commit/7cfcc79b0ab800959716738aff9419f53fc68c9c We are doing things like nb_sectors /= (s->qdev.blocksize / BDRV_SECTOR_SIZE); in the code here (e.g. in scsi_disk_emulate_mode_sense()), so if the blocksize is smaller than BDRV_SECTOR_SIZE (=512), this crashes with a division by 0 exception. Thus disallow block sizes of 256 bytes to avoid this situation. (From OE-Core rev: e9af3d328db8a32c22bb0798fa8dbb749e3f607b) Signed-off-by: Poonam Jadhav <poonam.jadhav@kpit.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-devtools/qemu/qemu.inc3
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2023-42467.patch46
-rw-r--r--meta/recipes-devtools/qemu/qemu/scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch54
-rw-r--r--meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch67
4 files changed, 170 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index d3e6ced988..ad6b310137 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -105,6 +105,9 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
105 file://CVE-2023-5088.patch \ 105 file://CVE-2023-5088.patch \
106 file://CVE-2024-24474.patch \ 106 file://CVE-2024-24474.patch \
107 file://CVE-2023-6693.patch \ 107 file://CVE-2023-6693.patch \
108 file://scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch \
109 file://scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch \
110 file://CVE-2023-42467.patch \
108 " 111 "
109UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" 112UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
110 113
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2023-42467.patch b/meta/recipes-devtools/qemu/qemu/CVE-2023-42467.patch
new file mode 100644
index 0000000000..d53683faa7
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2023-42467.patch
@@ -0,0 +1,46 @@
1From 7cfcc79b0ab800959716738aff9419f53fc68c9c Mon Sep 17 00:00:00 2001
2From: Thomas Huth <thuth@redhat.com>
3Date: Mon, 25 Sep 2023 11:18:54 +0200
4Subject: [PATCH] hw/scsi/scsi-disk: Disallow block sizes smaller than 512
5 [CVE-2023-42467]
6
7We are doing things like
8
9 nb_sectors /= (s->qdev.blocksize / BDRV_SECTOR_SIZE);
10
11in the code here (e.g. in scsi_disk_emulate_mode_sense()), so if
12the blocksize is smaller than BDRV_SECTOR_SIZE (=512), this crashes
13with a division by 0 exception. Thus disallow block sizes of 256
14bytes to avoid this situation.
15
16Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1813
17CVE: 2023-42467
18Signed-off-by: Thomas Huth <thuth@redhat.com>
19Message-ID: <20230925091854.49198-1-thuth@redhat.com>
20Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
21
22CVE: CVE-2023-42467
23Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/7cfcc79b0ab800959716738aff9419f53fc68c9c]
24Signed-off-by: Poonam Jadhav <poonam.jadhav@kpit.com>
25---
26 hw/scsi/scsi-disk.c | 5 +++--
27 1 file changed, 3 insertions(+), 2 deletions(-)
28
29diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
30index e0d79c7966c..477ee2bcd47 100644
31--- a/hw/scsi/scsi-disk.c
32+++ b/hw/scsi/scsi-disk.c
33@@ -1628,9 +1628,10 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
34 * Since the existing code only checks/updates bits 8-15 of the block
35 * size, restrict ourselves to the same requirement for now to ensure
36 * that a block size set by a block descriptor and then read back by
37- * a subsequent SCSI command will be the same
38+ * a subsequent SCSI command will be the same. Also disallow a block
39+ * size of 256 since we cannot handle anything below BDRV_SECTOR_SIZE.
40 */
41- if (bs && !(bs & ~0xff00) && bs != s->qdev.blocksize) {
42+ if (bs && !(bs & ~0xfe00) && bs != s->qdev.blocksize) {
43 s->qdev.blocksize = bs;
44 trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize);
45 }
46--
diff --git a/meta/recipes-devtools/qemu/qemu/scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch b/meta/recipes-devtools/qemu/qemu/scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch
new file mode 100644
index 0000000000..d8e48d07dd
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/scsi-disk-allow-MODE-SELECT-block-desriptor-to-set-the-block-size.patch
@@ -0,0 +1,54 @@
1From 356c4c441ec01910314c5867c680bef80d1dd373 Mon Sep 17 00:00:00 2001
2From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
3Date: Wed, 22 Jun 2022 11:53:12 +0100
4Subject: [PATCH] scsi-disk: allow MODE SELECT block descriptor to set the
5 block size
6
7The MODE SELECT command can contain an optional block descriptor that can be used
8to set the device block size. If the block descriptor is present then update the
9block size on the SCSI device accordingly.
10
11This allows CDROMs to be used with A/UX which requires a CDROM drive which is
12capable of switching from a 2048 byte sector size to a 512 byte sector size.
13
14Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
15Message-Id: <20220622105314.802852-13-mark.cave-ayland@ilande.co.uk>
16Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
17
18Comment: Patch is refreshed
19Upstream-Status: Backport [https://github.com/qemu/qemu/commit/356c4c441ec01910314c5867c680bef80d1dd373]
20Signed-off-by: Poonam Jadhav <poonam.jadhav@kpit.com>
21---
22 hw/scsi/scsi-disk.c | 6 ++++++
23 hw/scsi/trace-events | 1 +
24 2 files changed, 7 insertions(+)
25
26diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
27index db27e834dae3..f5cdb9ad4b54 100644
28--- a/hw/scsi/scsi-disk.c
29+++ b/hw/scsi/scsi-disk.c
30@@ -1616,6 +1616,12 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
31 goto invalid_param;
32 }
33
34+ /* Allow changing the block size */
35+ if (bd_len && p[6] != (s->qdev.blocksize >> 8)) {
36+ s->qdev.blocksize = p[6] << 8;
37+ trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize);
38+ }
39+
40 len -= bd_len;
41 p += bd_len;
42
43diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
44index 8e927ff62de1..ab238293f0da 100644
45--- a/hw/scsi/trace-events
46+++ b/hw/scsi/trace-events
47@@ -338,6 +338,7 @@scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PRId64 ", count %u)"
48 scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write %s(sector %" PRId64 ", count %u)"
49 scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: lun=%d tag=0x%x data=%s"
50 scsi_disk_aio_sgio_command(uint32_t tag, uint8_t cmd, uint64_t lba, int len, uint32_t timeout) "disk aio sgio: tag=0x%x cmd=0x%x (sector %" PRId64 ", count %d) timeout=%u"
51+scsi_disk_mode_select_set_blocksize(int blocksize) "set block size to %d"
52
53 # scsi-generic.c
54 scsi_generic_command_complete_noio(void *req, uint32_t tag, int statuc) "Command complete %p tag=0x%x status=%d"
diff --git a/meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch b/meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch
new file mode 100644
index 0000000000..1e1be683fc
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch
@@ -0,0 +1,67 @@
1From 55794c904df723109b228da28b5db778e0df3110 Mon Sep 17 00:00:00 2001
2From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
3Date: Sat, 30 Jul 2022 13:26:56 +0100
4Subject: [PATCH] scsi-disk: ensure block size is non-zero and changes limited
5 to bits 8-15
6
7The existing code assumes that the block size can be generated from p[1] << 8
8in multiple places which ignores the top and bottom 8 bits. If the block size
9is allowed to be set to an arbitrary value then this causes a mismatch
10between the value written by the guest in the block descriptor and the value
11subsequently read back using READ CAPACITY causing the guest to generate
12requests that can crash QEMU.
13
14For now restrict block size changes to bits 8-15 and also ignore requests to
15set the block size to 0 which causes the SCSI emulation to crash in at least
16one place with a divide by zero error.
17
18Fixes: 356c4c441e ("scsi-disk: allow MODE SELECT block descriptor to set the block size")
19Closes: https://gitlab.com/qemu-project/qemu/-/issues/1112
20Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
21Message-Id: <20220730122656.253448-3-mark.cave-ayland@ilande.co.uk>
22Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
23
24Comment: Patch is refreshed
25Upstream-Status: Backport [https://github.com/qemu/qemu/commit/55794c904df723109b228da28b5db778e0df3110]
26Signed-off-by: Poonam Jadhav <poonam.jadhav@kpit.com>
27---
28 hw/scsi/scsi-disk.c | 18 ++++++++++++++----
29 1 file changed, 14 insertions(+), 4 deletions(-)
30
31diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
32index 3027ac3b1ed6..efee6739f9ad 100644
33--- a/hw/scsi/scsi-disk.c
34+++ b/hw/scsi/scsi-disk.c
35@@ -1532,7 +1532,7 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
36 int cmd = r->req.cmd.buf[0];
37 int len = r->req.cmd.xfer;
38 int hdr_len = (cmd == MODE_SELECT ? 4 : 8);
39- int bd_len;
40+ int bd_len, bs;
41 int pass;
42
43 /* We only support PF=1, SP=0. */
44@@ -1617,9 +1617,19 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
45 }
46
47 /* Allow changing the block size */
48- if (bd_len && p[6] != (s->qdev.blocksize >> 8)) {
49- s->qdev.blocksize = p[6] << 8;
50- trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize);
51+ if (bd_len) {
52+ bs = p[5] << 16 | p[6] << 8 | p[7];
53+
54+ /*
55+ * Since the existing code only checks/updates bits 8-15 of the block
56+ * size, restrict ourselves to the same requirement for now to ensure
57+ * that a block size set by a block descriptor and then read back by
58+ * a subsequent SCSI command will be the same
59+ */
60+ if (bs && !(bs & ~0xff00) && bs != s->qdev.blocksize) {
61+ s->qdev.blocksize = bs;
62+ trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize);
63+ }
64 }
65
66 len -= bd_len;
67