]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/LsiScsiDxe: Examine the incoming SCSI Request Packet
authorGary Lin <glin@suse.com>
Fri, 17 Jul 2020 06:11:28 +0000 (14:11 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 17 Jul 2020 20:51:55 +0000 (20:51 +0000)
This is the first part of LsiScsiPassThru(). Before processing the SCSI
Request packet, we have to make sure whether the packet is valid or not.

v2: Make LsiScsiPassThru() return EFI_UNSUPPORTED since this function is
    half-implemented

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-10-glin@suse.com>

OvmfPkg/LsiScsiDxe/LsiScsi.c
OvmfPkg/LsiScsiDxe/LsiScsi.h

index 52c224aad9a5ac0380275000100034bd22816f9e..9859632e02d685a317073267c3be1d1268af34af 100644 (file)
@@ -52,6 +52,95 @@ LsiScsiReset (
   return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST);\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+ReportHostAdapterOverrunError (\r
+  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+  )\r
+{\r
+  Packet->SenseDataLength = 0;\r
+  Packet->HostAdapterStatus =\r
+            EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;\r
+  Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;\r
+  return EFI_BAD_BUFFER_SIZE;\r
+}\r
+\r
+/**\r
+\r
+  Check the request packet from the Extended SCSI Pass Thru Protocol. The\r
+  request packet is modified, to be forwarded outwards by LsiScsiPassThru(),\r
+  if invalid or unsupported parameters are detected.\r
+\r
+  @param[in] Dev          The LSI 53C895A SCSI device the packet targets.\r
+\r
+  @param[in] Target       The SCSI target controlled by the LSI 53C895A SCSI\r
+                          device.\r
+\r
+  @param[in] Lun          The Logical Unit Number under the SCSI target.\r
+\r
+  @param[in out] Packet   The Extended SCSI Pass Thru Protocol packet.\r
+\r
+\r
+  @retval EFI_SUCCESS  The Extended SCSI Pass Thru Protocol packet was valid.\r
+\r
+  @return              Otherwise, invalid or unsupported parameters were\r
+                       detected. Status codes are meant for direct forwarding\r
+                       by the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru()\r
+                       implementation.\r
+\r
+ **/\r
+STATIC\r
+EFI_STATUS\r
+LsiScsiCheckRequest (\r
+  IN LSI_SCSI_DEV                                   *Dev,\r
+  IN UINT8                                          Target,\r
+  IN UINT64                                         Lun,\r
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+  )\r
+{\r
+  if (Target > Dev->MaxTarget || Lun > Dev->MaxLun ||\r
+      Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||\r
+      //\r
+      // Trying to receive, but destination pointer is NULL, or contradicting\r
+      // transfer direction\r
+      //\r
+      (Packet->InTransferLength > 0 &&\r
+       (Packet->InDataBuffer == NULL ||\r
+        Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE\r
+         )\r
+        ) ||\r
+\r
+      //\r
+      // Trying to send, but source pointer is NULL, or contradicting transfer\r
+      // direction\r
+      //\r
+      (Packet->OutTransferLength > 0 &&\r
+       (Packet->OutDataBuffer == NULL ||\r
+        Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ\r
+         )\r
+        )\r
+    ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||\r
+      (Packet->InTransferLength > 0 && Packet->OutTransferLength > 0) ||\r
+      Packet->CdbLength > sizeof Dev->Dma->Cdb) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (Packet->InTransferLength > sizeof Dev->Dma->Data) {\r
+    Packet->InTransferLength = sizeof Dev->Dma->Data;\r
+    return ReportHostAdapterOverrunError (Packet);\r
+  }\r
+  if (Packet->OutTransferLength > sizeof Dev->Dma->Data) {\r
+    Packet->OutTransferLength = sizeof Dev->Dma->Data;\r
+    return ReportHostAdapterOverrunError (Packet);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 //\r
 // The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL\r
 // for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C,\r
@@ -70,6 +159,15 @@ LsiScsiPassThru (
   IN EFI_EVENT                                      Event     OPTIONAL\r
   )\r
 {\r
+  EFI_STATUS   Status;\r
+  LSI_SCSI_DEV *Dev;\r
+\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  Status = LsiScsiCheckRequest (Dev, *Target, Lun, Packet);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
index 9f9e5c7fed00c13307b9562ff3b8f2b18e93a5cc..05deeed379fea24fc4a8fec708b59509010c3529 100644 (file)
 #define _LSI_SCSI_DXE_H_\r
 \r
 typedef struct {\r
+  //\r
+  // The max size of CDB is 32.\r
+  //\r
+  UINT8                           Cdb[32];\r
   //\r
   // Allocate 64KB for read/write buffer. It seems sufficient for the common\r
   // boot scenarios.\r