All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use
@ 2020-03-05  8:31 Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

This series fixes a dangerous zero-length array use.
Simples patches first to clean the issue in the last patch:
dissociate the buffer holding DMA requests with pointer to
SRP Information Unit packets.

v2: Addressed David Gibson review comments

Philippe Mathieu-Daudé (5):
  hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include
  hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible
    array
  hw/scsi/spapr_vscsi: Simplify a bit
  hw/scsi/spapr_vscsi: Introduce req_iu() helper
  hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size

 hw/scsi/viosrp.h      |  3 ++-
 hw/scsi/spapr_vscsi.c | 59 ++++++++++++++++++++++++-------------------
 2 files changed, 35 insertions(+), 27 deletions(-)

-- 
2.21.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [MERGED PATCH v2 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
@ 2020-03-05  8:31 ` Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

This header use the srp_* structures declared in "hw/scsi/srp.h".

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
Patch already applied to ppc-for-5.0.

 hw/scsi/viosrp.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h
index d8e365db1e..25676c2383 100644
--- a/hw/scsi/viosrp.h
+++ b/hw/scsi/viosrp.h
@@ -34,6 +34,8 @@
 #ifndef PPC_VIOSRP_H
 #define PPC_VIOSRP_H
 
+#include "hw/scsi/srp.h"
+
 #define SRP_VERSION "16.a"
 #define SRP_MAX_IU_LEN    256
 #define SRP_MAX_LOC_LEN 32
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [MERGED PATCH v2 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé
@ 2020-03-05  8:31 ` Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

Replace sizeof() flexible arrays union srp_iu/viosrp_iu by the
SRP_MAX_IU_LEN definition, which is what this code actually meant
to use.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
Patch already applied to ppc-for-5.0.

 hw/scsi/spapr_vscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 7d584e7732..7e397ed797 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -671,8 +671,8 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
      */
     rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2);
     rsp->tag = tag;
-    rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu));
-    rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu));
+    rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
+    rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
     /* direct and indirect */
     rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT);
 
@@ -1088,7 +1088,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
      * in our 256 bytes IUs. If not we'll have to increase the size
      * of the structure.
      */
-    if (crq->s.IU_length > sizeof(union viosrp_iu)) {
+    if (crq->s.IU_length > SRP_MAX_IU_LEN) {
         fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n",
                 crq->s.IU_length);
         vscsi_put_req(req);
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [MERGED PATCH v2 3/5] hw/scsi/spapr_vscsi: Simplify a bit
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [MERGED PATCH v2 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé
@ 2020-03-05  8:31 ` Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [PATCH v2 4/5] hw/scsi/spapr_vscsi: Introduce req_iu() helper Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

We already have a ui pointer, use it (to simplify the next commit).

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
Patch already applied to ppc-for-5.0.

 hw/scsi/spapr_vscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 7e397ed797..3cb5a38181 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -261,9 +261,9 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
     if (status) {
         iu->srp.rsp.sol_not = (sol_not & 0x04) >> 2;
         if (req->senselen) {
-            req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
-            req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen);
-            memcpy(req->iu.srp.rsp.data, req->sense, req->senselen);
+            iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+            iu->srp.rsp.sense_data_len = cpu_to_be32(req->senselen);
+            memcpy(iu->srp.rsp.data, req->sense, req->senselen);
             total_len += req->senselen;
         }
     } else {
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/5] hw/scsi/spapr_vscsi: Introduce req_iu() helper
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2020-03-05  8:31 ` [MERGED PATCH v2 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé
@ 2020-03-05  8:31 ` Philippe Mathieu-Daudé
  2020-03-05  8:31 ` [PATCH v2 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé
  2020-03-05 10:27 ` [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

Introduce the req_iu() helper which returns a pointer to
the viosrp_iu union held in the vscsi_req structure.
This simplifies the next patch.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
v2: Simplify req_iu, rename 'ui -> iu' in commit description (dgibson)

 hw/scsi/spapr_vscsi.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 3cb5a38181..70547f98ac 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -97,6 +97,11 @@ typedef struct {
     vscsi_req reqs[VSCSI_REQ_LIMIT];
 } VSCSIState;
 
+static union viosrp_iu *req_iu(vscsi_req *req)
+{
+    return &req->iu;
+}
+
 static struct vscsi_req *vscsi_get_req(VSCSIState *s)
 {
     vscsi_req *req;
@@ -121,7 +126,7 @@ static struct vscsi_req *vscsi_find_req(VSCSIState *s, uint64_t srp_tag)
 
     for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
         req = &s->reqs[i];
-        if (req->iu.srp.cmd.tag == srp_tag) {
+        if (req_iu(req)->srp.cmd.tag == srp_tag) {
             return req;
         }
     }
@@ -188,7 +193,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
     req->crq.s.reserved = 0x00;
     req->crq.s.timeout = cpu_to_be16(0x0000);
     req->crq.s.IU_length = cpu_to_be16(length);
-    req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
+    req->crq.s.IU_data_ptr = req_iu(req)->srp.rsp.tag; /* right byte order */
 
     if (rc == 0) {
         req->crq.s.status = VIOSRP_OK;
@@ -224,7 +229,7 @@ static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req,
 static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
                           uint8_t status, int32_t res_in, int32_t res_out)
 {
-    union viosrp_iu *iu = &req->iu;
+    union viosrp_iu *iu = req_iu(req);
     uint64_t tag = iu->srp.rsp.tag;
     int total_len = sizeof(iu->srp.rsp);
     uint8_t sol_not = iu->srp.cmd.sol_not;
@@ -285,7 +290,7 @@ static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req,
                             unsigned n, unsigned buf_offset,
                             struct srp_direct_buf *ret)
 {
-    struct srp_cmd *cmd = &req->iu.srp.cmd;
+    struct srp_cmd *cmd = &req_iu(req)->srp.cmd;
 
     switch (req->dma_fmt) {
     case SRP_NO_DATA_DESC: {
@@ -473,7 +478,7 @@ static int data_out_desc_size(struct srp_cmd *cmd)
 
 static int vscsi_preprocess_desc(vscsi_req *req)
 {
-    struct srp_cmd *cmd = &req->iu.srp.cmd;
+    struct srp_cmd *cmd = &req_iu(req)->srp.cmd;
 
     req->cdb_offset = cmd->add_cdb_len & ~3;
 
@@ -655,7 +660,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq)
 
 static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
 {
-    union viosrp_iu *iu = &req->iu;
+    union viosrp_iu *iu = req_iu(req);
     struct srp_login_rsp *rsp = &iu->srp.login_rsp;
     uint64_t tag = iu->srp.rsp.tag;
 
@@ -681,7 +686,7 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
 
 static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)
 {
-    uint8_t *cdb = req->iu.srp.cmd.cdb;
+    uint8_t *cdb = req_iu(req)->srp.cmd.cdb;
     uint8_t resp_data[36];
     int rc, len, alen;
 
@@ -770,7 +775,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req)
 
 static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
 {
-    union srp_iu *srp = &req->iu.srp;
+    union srp_iu *srp = &req_iu(req)->srp;
     SCSIDevice *sdev;
     int n, lun;
 
@@ -821,7 +826,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
 
 static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
 {
-    union viosrp_iu *iu = &req->iu;
+    union viosrp_iu *iu = req_iu(req);
     vscsi_req *tmpreq;
     int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE;
     SCSIDevice *d;
@@ -831,7 +836,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
     fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n",
             iu->srp.tsk_mgmt.tsk_mgmt_func);
 
-    d = vscsi_device_find(&s->bus, be64_to_cpu(req->iu.srp.tsk_mgmt.lun), &lun);
+    d = vscsi_device_find(&s->bus,
+                          be64_to_cpu(req_iu(req)->srp.tsk_mgmt.lun), &lun);
     if (!d) {
         resp = SRP_TSK_MGMT_FIELDS_INVALID;
     } else {
@@ -842,7 +848,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
                 break;
             }
 
-            tmpreq = vscsi_find_req(s, req->iu.srp.tsk_mgmt.task_tag);
+            tmpreq = vscsi_find_req(s, req_iu(req)->srp.tsk_mgmt.task_tag);
             if (tmpreq && tmpreq->sreq) {
                 assert(tmpreq->sreq->hba_private);
                 scsi_req_cancel(tmpreq->sreq);
@@ -867,7 +873,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
 
             for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
                 tmpreq = &s->reqs[i];
-                if (tmpreq->iu.srp.cmd.lun != req->iu.srp.tsk_mgmt.lun) {
+                if (req_iu(tmpreq)->srp.cmd.lun
+                        != req_iu(req)->srp.tsk_mgmt.lun) {
                     continue;
                 }
                 if (!tmpreq->active || !tmpreq->sreq) {
@@ -911,7 +918,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
 
 static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req)
 {
-    union srp_iu *srp = &req->iu.srp;
+    union srp_iu *srp = &req_iu(req)->srp;
     int done = 1;
     uint8_t opcode = srp->rsp.opcode;
 
@@ -948,7 +955,7 @@ static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req)
     struct mad_adapter_info_data info;
     int rc;
 
-    sinfo = &req->iu.mad.adapter_info;
+    sinfo = &req_iu(req)->mad.adapter_info;
 
 #if 0 /* What for ? */
     rc = spapr_vio_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer),
@@ -984,7 +991,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req)
     uint64_t buffer;
     int rc;
 
-    vcap = &req->iu.mad.capabilities;
+    vcap = &req_iu(req)->mad.capabilities;
     req_len = len = be16_to_cpu(vcap->common.length);
     buffer = be64_to_cpu(vcap->buffer);
     if (len > sizeof(cap)) {
@@ -1029,7 +1036,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req)
 
 static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req)
 {
-    union mad_iu *mad = &req->iu.mad;
+    union mad_iu *mad = &req_iu(req)->mad;
     bool request_handled = false;
     uint64_t retlen = 0;
 
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2020-03-05  8:31 ` [PATCH v2 4/5] hw/scsi/spapr_vscsi: Introduce req_iu() helper Philippe Mathieu-Daudé
@ 2020-03-05  8:31 ` Philippe Mathieu-Daudé
  2020-03-05 10:27 ` [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-03-05  8:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

The 'union srp_iu' is meant as a pointer to any SRP Information
Unit type, it is not related to the size of a VIO DMA buffer.

Use a plain buffer for the VIO DMA read/write calls.
We can remove the reserved buffer from the 'union srp_iu'.

This issue was noticed when replacing the zero-length arrays
from hw/scsi/srp.h with flexible array member,
'clang -fsanitize=undefined' reported:

  hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 'union viosrp_iu' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
       union viosrp_iu         iu;
                               ^

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
v2: Removed unuseful _Static_assert (dgibson)

 hw/scsi/viosrp.h      |  1 -
 hw/scsi/spapr_vscsi.c | 10 +++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h
index 25676c2383..e5f9768e8f 100644
--- a/hw/scsi/viosrp.h
+++ b/hw/scsi/viosrp.h
@@ -49,7 +49,6 @@ union srp_iu {
     struct srp_tsk_mgmt tsk_mgmt;
     struct srp_cmd cmd;
     struct srp_rsp rsp;
-    uint8_t reserved[SRP_MAX_IU_LEN];
 };
 
 enum viosrp_crq_formats {
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 70547f98ac..acf9bb50bc 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -66,7 +66,7 @@ typedef union vscsi_crq {
 
 typedef struct vscsi_req {
     vscsi_crq               crq;
-    union viosrp_iu         iu;
+    uint8_t                 viosrp_iu_buf[SRP_MAX_IU_LEN];
 
     /* SCSI request tracking */
     SCSIRequest             *sreq;
@@ -99,7 +99,7 @@ typedef struct {
 
 static union viosrp_iu *req_iu(vscsi_req *req)
 {
-    return &req->iu;
+    return (union viosrp_iu *)req->viosrp_iu_buf;
 }
 
 static struct vscsi_req *vscsi_get_req(VSCSIState *s)
@@ -183,7 +183,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
 
     /* First copy the SRP */
     rc = spapr_vio_dma_write(&s->vdev, req->crq.s.IU_data_ptr,
-                             &req->iu, length);
+                             &req->viosrp_iu_buf, length);
     if (rc) {
         fprintf(stderr, "vscsi_send_iu: DMA write failure !\n");
     }
@@ -602,7 +602,7 @@ static const VMStateDescription vmstate_spapr_vscsi_req = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_BUFFER(crq.raw, vscsi_req),
-        VMSTATE_BUFFER(iu.srp.reserved, vscsi_req),
+        VMSTATE_BUFFER(viosrp_iu_buf, vscsi_req),
         VMSTATE_UINT32(qtag, vscsi_req),
         VMSTATE_BOOL(active, vscsi_req),
         VMSTATE_UINT32(data_len, vscsi_req),
@@ -1103,7 +1103,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
     }
 
     /* XXX Handle failure differently ? */
-    if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
+    if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->viosrp_iu_buf,
                            crq->s.IU_length)) {
         fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
         vscsi_put_req(req);
-- 
2.21.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use
  2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
                   ` (4 preceding siblings ...)
  2020-03-05  8:31 ` [PATCH v2 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé
@ 2020-03-05 10:27 ` Paolo Bonzini
  5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2020-03-05 10:27 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Fam Zheng, qemu-ppc, David Gibson

On 05/03/20 09:31, Philippe Mathieu-Daudé wrote:
> This series fixes a dangerous zero-length array use.
> Simples patches first to clean the issue in the last patch:
> dissociate the buffer holding DMA requests with pointer to
> SRP Information Unit packets.
> 
> v2: Addressed David Gibson review comments
> 
> Philippe Mathieu-Daudé (5):
>   hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include
>   hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible
>     array
>   hw/scsi/spapr_vscsi: Simplify a bit
>   hw/scsi/spapr_vscsi: Introduce req_iu() helper
>   hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size
> 
>  hw/scsi/viosrp.h      |  3 ++-
>  hw/scsi/spapr_vscsi.c | 59 ++++++++++++++++++++++++-------------------
>  2 files changed, 35 insertions(+), 27 deletions(-)
> 

I think this is clearer than the "reserved" member, and it gets one
important thing right though by decoupling SRP_MAX_IU_LEN from
sizeof(union srp_iu).

However it doesn't fix the actual time bomb, which is that,
vscsi_send_rsp can overrun the buffer size here depending on the length
of sense data:

	memcpy(req->iu.srp.rsp.data, req->sense, req->senselen);

But with this series in place we can fix that with just a couple of
asserts, like this:

/* This #define is why Phil's changes matter! */
#define SRP_MAX_IU_DATA_LEN (SRP_MAX_IU_LEN - sizeof(union srp_iu))

	/* in vscsi_send_rsp */
	int sense_data_len = MIN(req->senselen, SRP_MAX_IU_DATA_LEN);
	req->iu.srp.rsp.sense_data_len = cpu_to_be32(sense_data_len);
        memcpy(req->iu.srp.rsp.data, req->sense, sense_data_len);

	/* in vscsi_send_iu */
	assert(length < SRP_MAX_IU_LEN);

	/* in vscsi_process_tsk_mgmt */

	QEMU_BUILD_BUG_ON(SRP_MAX_IU_DATA_LEN < 4);

(Easier to write code than describe...).

Paolo



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-05 10:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-05  8:31 [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé
2020-03-05  8:31 ` [MERGED PATCH v2 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé
2020-03-05  8:31 ` [MERGED PATCH v2 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé
2020-03-05  8:31 ` [MERGED PATCH v2 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé
2020-03-05  8:31 ` [PATCH v2 4/5] hw/scsi/spapr_vscsi: Introduce req_iu() helper Philippe Mathieu-Daudé
2020-03-05  8:31 ` [PATCH v2 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé
2020-03-05 10:27 ` [PATCH v2 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.