summaryrefslogtreecommitdiffstats
path: root/include/hw/scsi
diff options
context:
space:
mode:
authorPaolo Bonzini2018-10-23 00:43:51 +0200
committerPaolo Bonzini2018-11-06 21:35:06 +0100
commit3d4a8bf0eed68a781e06118e4d1df6e2f106a1f2 (patch)
tree5c3862b3d67a85b00d86085ee1e9deef9fac1313 /include/hw/scsi
parentscsi-generic: avoid out-of-bounds access to VPD page list (diff)
downloadqemu-3d4a8bf0eed68a781e06118e4d1df6e2f106a1f2.tar.gz
qemu-3d4a8bf0eed68a781e06118e4d1df6e2f106a1f2.tar.xz
qemu-3d4a8bf0eed68a781e06118e4d1df6e2f106a1f2.zip
scsi-generic: avoid invalid access to struct when emulating block limits
Emulation of the block limits VPD page called back into scsi-disk.c, which however expected the request to be for a SCSIDiskState and accessed a scsi-generic device outside the bounds of its struct (namely to retrieve s->max_unmap_size and s->max_io_size). To avoid this, move the emulation code to a separate function that takes a new SCSIBlockLimits struct and marshals it into the VPD response format. Reported-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'include/hw/scsi')
-rw-r--r--include/hw/scsi/emulation.h16
-rw-r--r--include/hw/scsi/scsi.h1
2 files changed, 16 insertions, 1 deletions
diff --git a/include/hw/scsi/emulation.h b/include/hw/scsi/emulation.h
new file mode 100644
index 0000000000..09fba1ff39
--- /dev/null
+++ b/include/hw/scsi/emulation.h
@@ -0,0 +1,16 @@
+#ifndef HW_SCSI_EMULATION_H
+#define HW_SCSI_EMULATION_H 1
+
+typedef struct SCSIBlockLimits {
+ bool wsnz;
+ uint16_t min_io_size;
+ uint32_t max_unmap_descr;
+ uint32_t opt_io_size;
+ uint32_t max_unmap_sectors;
+ uint32_t unmap_sectors;
+ uint32_t max_io_sectors;
+} SCSIBlockLimits;
+
+int scsi_emulate_block_limits(uint8_t *outbuf, const SCSIBlockLimits *bl);
+
+#endif
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index ee3a4118fb..acef25faa4 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -189,7 +189,6 @@ void scsi_device_report_change(SCSIDevice *dev, SCSISense sense);
void scsi_device_unit_attention_reported(SCSIDevice *dev);
void scsi_generic_read_device_inquiry(SCSIDevice *dev);
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
-int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf);
int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
uint8_t *buf, uint8_t buf_size);
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);