Patch "qla2xxx: Terminate exchange if corrupted" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
qla2xxx: Terminate exchange if corrupted
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
qla2xxx-terminate-exchange-if-corrupted.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Jul 3 11:12:14 CEST 2017
From: Quinn Tran <[email protected]>
Date: Fri, 23 Dec 2016 18:06:11 -0800
Subject: qla2xxx: Terminate exchange if corrupted
From: Quinn Tran <[email protected]>
[ Upstream commit 5f35509db179ca7ed1feaa4b14f841adb06ed220 ]
Corrupted 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 dropped or terminated if corrupted.
--- drivers/scsi/qla2xxx/qla_def.h | 3 ++- drivers/scsi/qla2xxx/qla_target.c | 23 ++++++++++++++++++++--- drivers/scsi/qla2xxx/qla_target.h | 22 +++++++++++++++++++++- 3 files changed, 43 insertions(+), 5 deletions(-)
drivers/scsi/qla2xxx/qla_def.h +2 -1
@@ -1555,7 +1555,8 @@ typedef struct {struct atio {uint8_t entry_type;/* Entry type. */ uint8_t entry_count;/* Entry count. */ -uint8_t data[58 ]; +__le16 attr_n_length; +uint8_t data[56 ];uint32_t signature;#define ATIO_PROCESSED 0xDEADDEAD/* Signature */ };
drivers/scsi/qla2xxx/qla_target.c +20 -3
@@ -6463,12 +6463,29 @@ qlt_24xx_process_atio_queue(struct scsi_if (!vha->flags.online)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,0xffff , +"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); + +adjust_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++;
drivers/scsi/qla2xxx/qla_target.h +21 -1
@@ -427,13 +427,33 @@ struct atio_from_isp {struct {uint8_t entry_type;/* Entry type. */ uint8_t entry_count;/* Entry count. */ -uint8_t data[58 ]; +__le16 attr_n_length; +#define FCP_CMD_LENGTH_MASK 0x0fff +#define FCP_CMD_LENGTH_MIN 0x38 +uint8_t data[56 ];uint32_t signature;#define ATIO_PROCESSED 0xDEADDEAD/* Signature */ } raw; } u; } __packed; +static inline int fcpcmd_is_corrupted (struct atio *atio) +{ +if (atio->entry_type ==ATIO_TYPE7 && + (le16_to_cpu (atio->attr_n_length &FCP_CMD_LENGTH_MASK ) < +FCP_CMD_LENGTH_MIN )) +return 1 ; +else +return 0 ; +} + +/* adjust corrupted atio so we won't trip over the same entry again. */ +static inline void adjust_corrupted_atio (struct atio_from_isp *atio) +{ + atio->u.raw.attr_n_length =cpu_to_le16 (FCP_CMD_LENGTH_MIN ); + atio->u.isp24.fcp_cmnd.add_cdb_len =0 ; +} +#define CTIO_TYPE7 0x12/* Continue target I/O entry (for 24xx) */ /*
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/qla2xxx-fix-erroneous-invalid-handle-message.patch queue-4.9/qla2xxx-terminate-exchange-if-corrupted.patch