Blame SOURCES/smartmontools-7.0-cciss-smallbuf-segfault.patch

2ff39e
Index: cciss.cpp
2ff39e
===================================================================
2ff39e
--- a/cciss.cpp	(revision 4975)
2ff39e
+++ a/cciss.cpp	(working copy)
2ff39e
@@ -71,10 +71,12 @@
2ff39e
 */
2ff39e
 int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report)
2ff39e
 {
2ff39e
-     unsigned char pBuf[512] = {0};
2ff39e
+     switch (iop->dxfer_dir) {
2ff39e
+        case DXFER_NONE: case DXFER_FROM_DEVICE: break;
2ff39e
+        default: return -ENOTSUP; // TODO: Support DXFER_TO_DEVICE
2ff39e
+     }
2ff39e
+
2ff39e
      unsigned char phylun[8] = {0};
2ff39e
-     int iBufLen = 512;
2ff39e
-     int len = 0; // used later in the code.
2ff39e
  
2ff39e
      int status = cciss_getlun(device, target, phylun, report);
2ff39e
      if (report > 0)
2ff39e
@@ -85,6 +87,10 @@
2ff39e
          return -ENXIO;      /* give up, assume no device there */
2ff39e
      }
2ff39e
 
2ff39e
+     unsigned char sensebuf[SEND_IOCTL_RESP_SENSE_LEN];
2ff39e
+     unsigned char * pBuf = (iop->dxferp ? iop->dxferp : sensebuf);
2ff39e
+     unsigned iBufLen = (iop->dxferp ? iop->dxfer_len : sizeof(sensebuf));
2ff39e
+
2ff39e
      status = cciss_sendpassthru( 2, iop->cmnd, iop->cmnd_len, (char*) pBuf, iBufLen, 1, phylun, device);
2ff39e
  
2ff39e
      if (0 == status)
2ff39e
@@ -93,7 +99,6 @@
2ff39e
              printf("  status=0\n");
2ff39e
          if (DXFER_FROM_DEVICE == iop->dxfer_dir)
2ff39e
          {
2ff39e
-             memcpy(iop->dxferp, pBuf, iop->dxfer_len);
2ff39e
              if (report > 1)
2ff39e
              {
2ff39e
                  int trunc = (iop->dxfer_len > 256) ? 1 : 0;
2ff39e
@@ -107,13 +112,15 @@
2ff39e
      iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
2ff39e
      if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
2ff39e
          iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
2ff39e
-     len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
2ff39e
-                SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
2ff39e
+     unsigned len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
2ff39e
+                     SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
2ff39e
+     if (len > iBufLen)
2ff39e
+       len = iBufLen;
2ff39e
      if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
2ff39e
          iop->sensep && (len > 0))
2ff39e
      {
2ff39e
          memcpy(iop->sensep, pBuf, len);
2ff39e
-         iop->resp_sense_len = iBufLen;
2ff39e
+         iop->resp_sense_len = len;
2ff39e
          if (report > 1)
2ff39e
          {
2ff39e
              printf("  >>> Sense buffer, len=%d:\n", (int)len);
2ff39e
@@ -173,7 +180,7 @@
2ff39e
     iocommand.Request.CDBLen = CDBlen;
2ff39e
     iocommand.Request.Type.Type = TYPE_CMD;
2ff39e
     iocommand.Request.Type.Attribute = ATTR_SIMPLE;
2ff39e
-    iocommand.Request.Type.Direction = XFER_READ;
2ff39e
+    iocommand.Request.Type.Direction = XFER_READ; // TODO: OK for DXFER_NONE ?
2ff39e
     iocommand.Request.Timeout = 0;
2ff39e
 
2ff39e
     iocommand.buf_size = size;