qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 11/41] megasas: do not read command more than once from frame
Date: Thu, 15 Jun 2017 12:52:31 +0200	[thread overview]
Message-ID: <1497523981-38449-12-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1497523981-38449-1-git-send-email-pbonzini@redhat.com>

Avoid TOC-TOU bugs by passing the frame_cmd down, and checking
cmd->dcmd_opcode instead of cmd->frame->header.frame_cmd.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/megasas.c | 60 +++++++++++++++++++++++--------------------------------
 1 file changed, 25 insertions(+), 35 deletions(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index a3f75c1..38e0a2f 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1591,12 +1591,13 @@ static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
 }
 
 static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
-                                        SCSIRequest *req)
+                                        SCSIRequest *req, size_t resid)
 {
     int retval = MFI_STAT_OK;
     int lun = req->lun;
 
     trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun);
+    cmd->iov_size -= resid;
     switch (cmd->dcmd_opcode) {
     case MFI_DCMD_PD_GET_INFO:
         retval = megasas_pd_get_info_submit(req->dev, lun, cmd);
@@ -1649,11 +1650,12 @@ static int megasas_enqueue_req(MegasasCmd *cmd, bool is_write)
 }
 
 static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
-                               bool is_logical)
+                               int frame_cmd)
 {
     uint8_t *cdb;
     bool is_write;
     struct SCSIDevice *sdev = NULL;
+    bool is_logical = (frame_cmd == MFI_CMD_LD_SCSI_IO);
 
     cdb = cmd->frame->pass.cdb;
 
@@ -1661,7 +1663,7 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
         if (cmd->frame->header.target_id >= MFI_MAX_LD ||
             cmd->frame->header.lun_id != 0) {
             trace_megasas_scsi_target_not_present(
-                mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
+                mfi_frame_desc[frame_cmd], is_logical,
                 cmd->frame->header.target_id, cmd->frame->header.lun_id);
             return MFI_STAT_DEVICE_NOT_FOUND;
         }
@@ -1671,19 +1673,20 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
 
     cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
     trace_megasas_handle_scsi(mfi_frame_desc[cmd->frame->header.frame_cmd],
-                              is_logical, cmd->frame->header.target_id,
+    trace_megasas_handle_scsi(mfi_frame_desc[frame_cmd], is_logical,
+                              cmd->frame->header.target_id,
                               cmd->frame->header.lun_id, sdev, cmd->iov_size);
 
     if (!sdev || (megasas_is_jbod(s) && is_logical)) {
         trace_megasas_scsi_target_not_present(
-            mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
+            mfi_frame_desc[frame_cmd], is_logical,
             cmd->frame->header.target_id, cmd->frame->header.lun_id);
         return MFI_STAT_DEVICE_NOT_FOUND;
     }
 
     if (cmd->frame->header.cdb_len > 16) {
         trace_megasas_scsi_invalid_cdb_len(
-                mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
+                mfi_frame_desc[frame_cmd], is_logical,
                 cmd->frame->header.target_id, cmd->frame->header.lun_id,
                 cmd->frame->header.cdb_len);
         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
@@ -1703,7 +1706,7 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
                             cmd->frame->header.lun_id, cdb, cmd);
     if (!cmd->req) {
         trace_megasas_scsi_req_alloc_failed(
-                mfi_frame_desc[cmd->frame->header.frame_cmd],
+                mfi_frame_desc[frame_cmd],
                 cmd->frame->header.target_id, cmd->frame->header.lun_id);
         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
         cmd->frame->header.scsi_status = BUSY;
@@ -1725,11 +1728,11 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
     return MFI_STAT_INVALID_STATUS;
 }
 
-static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd)
+static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
 {
     uint32_t lba_count, lba_start_hi, lba_start_lo;
     uint64_t lba_start;
-    bool is_write = (cmd->frame->header.frame_cmd == MFI_CMD_LD_WRITE);
+    bool is_write = (frame_cmd == MFI_CMD_LD_WRITE);
     uint8_t cdb[16];
     int len;
     struct SCSIDevice *sdev = NULL;
@@ -1746,20 +1749,20 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd)
     }
 
     trace_megasas_handle_io(cmd->index,
-                            mfi_frame_desc[cmd->frame->header.frame_cmd],
+                            mfi_frame_desc[frame_cmd],
                             cmd->frame->header.target_id,
                             cmd->frame->header.lun_id,
                             (unsigned long)lba_start, (unsigned long)lba_count);
     if (!sdev) {
         trace_megasas_io_target_not_present(cmd->index,
-            mfi_frame_desc[cmd->frame->header.frame_cmd],
+            mfi_frame_desc[frame_cmd],
             cmd->frame->header.target_id, cmd->frame->header.lun_id);
         return MFI_STAT_DEVICE_NOT_FOUND;
     }
 
     if (cmd->frame->header.cdb_len > 16) {
         trace_megasas_scsi_invalid_cdb_len(
-            mfi_frame_desc[cmd->frame->header.frame_cmd], 1,
+            mfi_frame_desc[frame_cmd], 1,
             cmd->frame->header.target_id, cmd->frame->header.lun_id,
             cmd->frame->header.cdb_len);
         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
@@ -1781,7 +1784,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd)
                             cmd->frame->header.lun_id, cdb, cmd);
     if (!cmd->req) {
         trace_megasas_scsi_req_alloc_failed(
-            mfi_frame_desc[cmd->frame->header.frame_cmd],
+            mfi_frame_desc[frame_cmd],
             cmd->frame->header.target_id, cmd->frame->header.lun_id);
         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
         cmd->frame->header.scsi_status = BUSY;
@@ -1799,23 +1802,11 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd)
     return MFI_STAT_INVALID_STATUS;
 }
 
-static int megasas_finish_internal_command(MegasasCmd *cmd,
-                                           SCSIRequest *req, size_t resid)
-{
-    int retval = MFI_STAT_INVALID_CMD;
-
-    if (cmd->frame->header.frame_cmd == MFI_CMD_DCMD) {
-        cmd->iov_size -= resid;
-        retval = megasas_finish_internal_dcmd(cmd, req);
-    }
-    return retval;
-}
-
 static QEMUSGList *megasas_get_sg_list(SCSIRequest *req)
 {
     MegasasCmd *cmd = req->hba_private;
 
-    if (cmd->frame->header.frame_cmd == MFI_CMD_DCMD) {
+    if (cmd->dcmd_opcode != -1) {
         return NULL;
     } else {
         return &cmd->qsg;
@@ -1829,7 +1820,7 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
 
     trace_megasas_io_complete(cmd->index, len);
 
-    if (cmd->frame->header.frame_cmd != MFI_CMD_DCMD) {
+    if (cmd->dcmd_opcode != -1) {
         scsi_req_continue(req);
         return;
     }
@@ -1872,7 +1863,7 @@ static void megasas_command_complete(SCSIRequest *req, uint32_t status,
         /*
          * Internal command complete
          */
-        cmd_status = megasas_finish_internal_command(cmd, req, resid);
+        cmd_status = megasas_finish_internal_dcmd(cmd, req, resid);
         if (cmd_status == MFI_STAT_INVALID_STATUS) {
             return;
         }
@@ -1943,6 +1934,7 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
 {
     uint8_t frame_status = MFI_STAT_INVALID_CMD;
     uint64_t frame_context;
+    int frame_cmd;
     MegasasCmd *cmd;
 
     /*
@@ -1961,7 +1953,8 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
         s->event_count++;
         return;
     }
-    switch (cmd->frame->header.frame_cmd) {
+    frame_cmd = cmd->frame->header.frame_cmd;
+    switch (frame_cmd) {
     case MFI_CMD_INIT:
         frame_status = megasas_init_firmware(s, cmd);
         break;
@@ -1972,18 +1965,15 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
         frame_status = megasas_handle_abort(s, cmd);
         break;
     case MFI_CMD_PD_SCSI_IO:
-        frame_status = megasas_handle_scsi(s, cmd, 0);
-        break;
     case MFI_CMD_LD_SCSI_IO:
-        frame_status = megasas_handle_scsi(s, cmd, 1);
+        frame_status = megasas_handle_scsi(s, cmd, frame_cmd);
         break;
     case MFI_CMD_LD_READ:
     case MFI_CMD_LD_WRITE:
-        frame_status = megasas_handle_io(s, cmd);
+        frame_status = megasas_handle_io(s, cmd, frame_cmd);
         break;
     default:
-        trace_megasas_unhandled_frame_cmd(cmd->index,
-                                          cmd->frame->header.frame_cmd);
+        trace_megasas_unhandled_frame_cmd(cmd->index, frame_cmd);
         s->event_count++;
         break;
     }
-- 
1.8.3.1

  parent reply	other threads:[~2017-06-15 10:53 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-15 10:52 [Qemu-devel] [PULL 00/41] Misc patches for 2017-06-15 Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 01/41] exec: check kvm mmu notifiers earlier Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 02/41] exec: split file_ram_alloc() Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 03/41] exec: split qemu_ram_alloc_from_file() Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 04/41] Add memory_region_init_ram_from_fd() Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 05/41] ivshmem: use ram_from_fd() Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 06/41] memory: remove memory_region_set_fd Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 07/41] megasas: add qtest Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 08/41] megasas: do not read sense length more than once from frame Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 09/41] megasas: do not read iovec count " Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 10/41] megasas: do not read DCMD opcode " Paolo Bonzini
2017-06-15 10:52 ` Paolo Bonzini [this message]
2017-06-15 10:52 ` [Qemu-devel] [PULL 12/41] megasas: do not read SCSI req parameters " Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 13/41] megasas: always store SCSIRequest* into MegasasCmd Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 14/41] Makefile: Do not generate files if "configure" has not been run yet Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 15/41] vl: Fix broken thread=xxx option of the --accel parameter Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 16/41] kvm-all: make async_safe_run_on_cpu safe on kvm too Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 17/41] hax-all: make async_safe_run_on_cpu safe on HAX too Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 18/41] nbd: Fix regression on resiliency to port scan Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 19/41] qemu-nbd: Ignore SIGPIPE Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 20/41] accel: split the tcg accelerator from accel.c file Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 21/41] tcg: move tcg related files into accel/tcg/ subdirectory Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 22/41] tcg: move tcg backend files into accel/tcg/ Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 23/41] accel: move kvm related accelerator files into accel/ Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 24/41] nbd: rename read_sync and friends Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 25/41] nbd: make nbd_drop public Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 26/41] nbd/server: get rid of nbd_negotiate_read and friends Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 27/41] nbd/server: get rid of ssize_t Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 28/41] nbd/server: refactor nbd_co_send_reply Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 29/41] nbd/server: get rid of EAGAIN dead code Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 30/41] nbd/server: refactor nbd_co_receive_request Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 31/41] nbd/server: remove NBDClientNewData Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 32/41] nbd/server: nbd_negotiate: fix error path Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 33/41] nbd/server: get rid of fail: return rc Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 34/41] nbd/server: rename rc to ret Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 35/41] nbd/server: refactor nbd_trip Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 36/41] include/exec/poison: Add missing TARGET defines Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 37/41] include/exec/poison: Mark some CONFIG defines as poisoned, too Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 38/41] docs: create interop/ subdirectory Paolo Bonzini
2017-06-15 10:52 ` [Qemu-devel] [PULL 39/41] qemu-doc: include version number Paolo Bonzini
2017-06-15 10:53 ` [Qemu-devel] [PULL 40/41] vhost-user-scsi: Introduce vhost-user-scsi host device Paolo Bonzini
2017-07-18 16:32   ` Marc-André Lureau
2017-07-23 14:47     ` Paolo Bonzini
2017-06-15 10:53 ` [Qemu-devel] [PULL 41/41] vhost-user-scsi: Introduce a vhost-user-scsi sample application Paolo Bonzini
2017-06-20 15:00 ` [Qemu-devel] [PULL 00/41] Misc patches for 2017-06-15 Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1497523981-38449-12-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).