diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch | 67 |
1 files changed, 67 insertions, 0 deletions
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 @@ +From 55794c904df723109b228da28b5db778e0df3110 Mon Sep 17 00:00:00 2001 +From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> +Date: Sat, 30 Jul 2022 13:26:56 +0100 +Subject: [PATCH] scsi-disk: ensure block size is non-zero and changes limited + to bits 8-15 + +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. + +Fixes: 356c4c441e ("scsi-disk: allow MODE SELECT block descriptor to set the block size") +Closes: https://gitlab.com/qemu-project/qemu/-/issues/1112 +Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> +Message-Id: <20220730122656.253448-3-mark.cave-ayland@ilande.co.uk> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> + +Comment: Patch is refreshed +Upstream-Status: Backport [https://github.com/qemu/qemu/commit/55794c904df723109b228da28b5db778e0df3110] +Signed-off-by: Poonam Jadhav <poonam.jadhav@kpit.com> +--- + hw/scsi/scsi-disk.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 3027ac3b1ed6..efee6739f9ad 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -1532,7 +1532,7 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf) + int cmd = r->req.cmd.buf[0]; + int len = r->req.cmd.xfer; + int hdr_len = (cmd == MODE_SELECT ? 4 : 8); +- int bd_len; ++ int bd_len, bs; + int pass; + + /* We only support PF=1, SP=0. */ +@@ -1617,9 +1617,19 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf) + } + + /* Allow changing the block size */ +- if (bd_len && p[6] != (s->qdev.blocksize >> 8)) { +- s->qdev.blocksize = p[6] << 8; +- trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize); ++ if (bd_len) { ++ bs = p[5] << 16 | p[6] << 8 | p[7]; ++ ++ /* ++ * Since the existing code only checks/updates bits 8-15 of the block ++ * size, restrict ourselves to the same requirement for now to ensure ++ * that a block size set by a block descriptor and then read back by ++ * a subsequent SCSI command will be the same ++ */ ++ if (bs && !(bs & ~0xff00) && bs != s->qdev.blocksize) { ++ s->qdev.blocksize = bs; ++ trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize); ++ } + } + + len -= bd_len; + |