summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp')
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
index a2864b84..2b8a9a07 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
@@ -67,6 +67,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
{
bool fProcessed = true;
+ if (!pVScsiReq->cbCDB)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ return true;
+ }
+
switch (pVScsiReq->pbCDB[0])
{
case SCSI_INQUIRY:
@@ -92,6 +99,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REPORT_LUNS:
{
+ if (pVScsiReq->cbCDB < 10)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
/*
* If allocation length is less than 16 bytes SPC compliant devices have
* to return an error.
@@ -127,6 +141,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REQUEST_SENSE:
{
+ if (pVScsiReq->cbCDB < 5)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
vscsiReqSetXferDir(pVScsiReq, VSCSIXFERDIR_T2I);
vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
@@ -140,6 +161,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
#if 0
case SCSI_MAINTENANCE_IN:
{
+ if (pVScsiReq->cbCDB < 8)
+ {
+ *prcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
if (pVScsiReq->pbCDB[1] == SCSI_MAINTENANCE_IN_REPORT_SUPP_OPC)
{
/*
@@ -374,7 +402,26 @@ VBOXDDU_DECL(int) VSCSIDeviceReqEnqueue(VSCSIDEVICE hVScsiDevice, VSCSIREQ hVScs
if (vscsiDeviceLunIsPresent(pVScsiDevice, pVScsiReq->iLun))
{
PVSCSILUNINT pVScsiLun = pVScsiDevice->papVScsiLun[pVScsiReq->iLun];
- rc = pVScsiLun->pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ PVSCSILUNDESC pVScsiLunDesc = pVScsiLun->pVScsiLunDesc;
+ uint8_t const bOpc = pVScsiReq->pbCDB[0];
+ uint8_t const cbCdbMin = pVScsiLunDesc->pacbCdbOpc[bOpc];
+
+ /* Fail if the opcode is not supported or the CDB is too short. */
+ if ( cbCdbMin != VSCSI_LUN_CDB_SZ_INVALID
+ && pVScsiReq->cbCDB >= cbCdbMin)
+ rc = pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ else
+ {
+ /*
+ * CDB length is smaller than what the LUN expects, respond with an
+ * ILLEGAL OPCODE error.
+ */
+ vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+
+ vscsiDeviceReqComplete(pVScsiDevice, pVScsiReq,
+ SCSI_STATUS_CHECK_CONDITION, false, VINF_SUCCESS);
+ }
}
else
{