Re: [PATCH 22/22] qla2xxx: Add check for corrupt ATIO.

2016-12-07 Thread Hannes Reinecke
On 12/06/2016 09:30 PM, Himanshu Madhani wrote:
> From: Quinn Tran 
> 
> corrupt ATIO is defined as length of fcp_header & fcp_cmd
> payload is less than 0x38. It's the minimum size for a frame to
> carry 8..16 bytes SCSI CDB. The exchange will be drop or
> terminated if corrupted
> 
> Signed-off-by: Quinn Tran 
> Signed-off-by: Himanshu Madhani 
> ---
>  drivers/scsi/qla2xxx/qla_def.h|  3 ++-
>  drivers/scsi/qla2xxx/qla_target.c | 23 ---
>  drivers/scsi/qla2xxx/qla_target.h | 16 +++-
>  3 files changed, 37 insertions(+), 5 deletions(-)
> 
Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries & Storage
h...@suse.com  +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 22/22] qla2xxx: Add check for corrupt ATIO.

2016-12-06 Thread Himanshu Madhani
From: Quinn Tran 

corrupt ATIO is defined as length of fcp_header & fcp_cmd
payload is less than 0x38. It's the minimum size for a frame to
carry 8..16 bytes SCSI CDB. The exchange will be drop or
terminated if corrupted

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  3 ++-
 drivers/scsi/qla2xxx/qla_target.c | 23 ---
 drivers/scsi/qla2xxx/qla_target.h | 16 +++-
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index de058a1..e1e686f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1600,7 +1600,8 @@ struct link_statistics {
 struct atio {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count;/* Entry count. */
-   uint8_t data[58];
+   uint16_t attr_n_length;
+   uint8_t  data[56];
uint32_tsignature;
 #define ATIO_PROCESSED 0xDEADDEAD  /* Signature */
 };
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 6f01c66..c7093c79 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -6967,12 +6967,29 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
if (!ha->flags.fw_started)
return;
 
-   while (ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) {
+   while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) ||
+  FCPCMD_IS_CORRUPTED(ha->tgt.atio_ring_ptr)) {
pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr;
cnt = pkt->u.raw.entry_count;
 
-   qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt,
-   ha_locked);
+   if (unlikely(FCPCMD_IS_CORRUPTED(ha->tgt.atio_ring_ptr))) {
+   /* This packet is corrupted.  The header + payload
+* can not be trusted.  There is no point in passing
+* it further up.
+*/
+   ql_log(ql_log_warn, vha, 0x,
+  "corrupted fcp frame SID[%3phN] "
+  "OXID[%04x] EXCG[%x] %64phN\n",
+  pkt->u.isp24.fcp_hdr.s_id,
+  be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id),
+  le32_to_cpu(pkt->u.isp24.exchange_addr),
+  pkt);
+
+   ADJ_CORRUPTED_ATIO(pkt);
+   qlt_send_term_exchange(vha, NULL, pkt, ha_locked, 0);
+   } else
+   qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp 
*)pkt,
+   ha_locked);
 
for (i = 0; i < cnt; i++) {
ha->tgt.atio_ring_index++;
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index b57067d..3aff551 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -429,7 +429,10 @@ struct atio_from_isp {
struct {
uint8_t  entry_type;/* Entry type. */
uint8_t  entry_count;   /* Entry count. */
-   uint8_t  data[58];
+   uint16_t attr_n_length;
+#define FCP_CMD_LENTH_MASK 0x0fff
+#define FCP_CMD_LENTH_MIN  0x38
+   uint8_t  data[56];
uint32_t signature;
 #define ATIO_PROCESSED 0xDEADDEAD  /* Signature */
} raw;
@@ -437,6 +440,17 @@ struct atio_from_isp {
 } __packed;
 
 
+#define FCPCMD_IS_CORRUPTED(_a) \
+((_a->entry_type == ATIO_TYPE7) && \
+((le16_to_cpu(_a->attr_n_length) & FCP_CMD_LENTH_MASK) < FCP_CMD_LENTH_MIN))
+
+/* adjust corrupted atio so we won't trip over the same entry again. */
+#define ADJ_CORRUPTED_ATIO(_a)  \
+{   \
+_a->u.raw.attr_n_length = cpu_to_le16(FCP_CMD_LENTH_MIN); \
+((struct atio_from_isp *)_a)->u.isp24.fcp_cmnd.add_cdb_len = 0; \
+}
+
 #define GET_DL_FR_ATIO(_atio)  \
(be32_to_cpu(get_unaligned((uint32_t *) \
 &_atio->u.isp24.fcp_cmnd.add_cdb[_atio->u.isp24.fcp_cmnd.add_cdb_len*4])))
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html