提交 5f35509d 编写于 作者: Q Quinn Tran 提交者: Bart Van Assche

qla2xxx: Terminate exchange if corrupted

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.
Signed-off-by: NQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: NHimanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
[ bvanassche: Fixed spelling in patch title ]
Signed-off-by: NBart Van Assche <bart.vanassche@sandisk.com>
上级 fc1ffd6c
......@@ -1556,7 +1556,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 */
};
......
......@@ -6454,12 +6454,29 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
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++;
......
......@@ -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) */
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册