From e71ba7d6434cb8f1738e9160f31c83f324a66bc1 Mon Sep 17 00:00:00 2001
Message-Id: <e71ba7d6434cb8f1738e9160f31c83f324a66bc1.1343041017.git.minovotn@redhat.com>
In-Reply-To: <1265c14a6676be3cbc003c219326a60813dc29d5.1343041017.git.minovotn@redhat.com>
References: <1265c14a6676be3cbc003c219326a60813dc29d5.1343041017.git.minovotn@redhat.com>
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 12 Jul 2012 12:11:21 +0200
Subject: [PATCH 6/9] scsi: do not report bogus overruns for commands in the
 0x00-0x1F range

RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
Message-id: <fba10ae8fe1f08b8a2d7c748e0604329312008da.1342100155.git.mrezanin@redhat.com>
Patchwork-id: 40284
O-Subject: [RHEL6 qemu-kvm PATCH 3/5] scsi: do not report bogus overruns for commands in the 0x00-0x1F range
Bugzilla: 825188
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>

From: Paolo Bonzini <pbonzini@redhat.com>

Upstream relationship: f62d059

Interpreting cdb[4] == 0 as a request to transfer 256 blocks is only
needed for READ_6 and WRITE_6.  No other command in that range needs
that special-casing, and the resulting overrun breaks scsi-testsuite's
attempt to use command 2 as a known-invalid command.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi-bus.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/scsi-bus.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 1ba050e..4934580 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -697,10 +697,6 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case 0:
         cmd->xfer = (uint64_t) buf[4];
         cmd->len = 6;
-        /* length 0 means 256 blocks */
-        if (cmd->xfer == 0) {
-            cmd->xfer = 256;
-        }
         break;
     case 1:
     case 2:
@@ -771,18 +767,26 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
             cmd->xfer = buf[9] | (buf[8] << 8);
         }
         break;
+    case WRITE_6:
+        /* length 0 means 256 blocks */
+        if (cmd->xfer == 0) {
+            cmd->xfer = 256;
+        }
     case WRITE_10:
     case WRITE_VERIFY_10:
-    case WRITE_6:
     case WRITE_12:
     case WRITE_VERIFY_12:
     case WRITE_16:
     case WRITE_VERIFY_16:
         cmd->xfer *= dev->blocksize;
         break;
-    case READ_10:
     case READ_6:
     case READ_REVERSE:
+        /* length 0 means 256 blocks */
+        if (cmd->xfer == 0) {
+            cmd->xfer = 256;
+        }
+    case READ_10:
     case RECOVER_BUFFERED_DATA:
     case READ_12:
     case READ_16:
-- 
1.7.10.4

