summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-10-13 15:10:55 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2016-11-08 23:29:53 +0100
commite0a25286d8acd97ac0b9db5b8b776755fc8b62fa (patch)
tree52b0da38545da53f53455a9159e0693846198d0f /drivers/scsi/libfc
parentscsi: libfc: wait for E_D_TOV when out-of-order sequence is received (diff)
downloadlinux-e0a25286d8acd97ac0b9db5b8b776755fc8b62fa.tar.xz
linux-e0a25286d8acd97ac0b9db5b8b776755fc8b62fa.zip
scsi: libfc: Check xid when looking up REC exchanges
We currently can only lookup the local xid, so we need to reject REC with empty rxid. Signed-off-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_exch.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 44feffa2ee25..9921dbbaeaff 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -2005,8 +2005,7 @@ static void fc_exch_els_rec(struct fc_frame *rfp)
enum fc_els_rjt_reason reason = ELS_RJT_LOGIC;
enum fc_els_rjt_explan explan;
u32 sid;
- u16 rxid;
- u16 oxid;
+ u16 xid, rxid, oxid;
lport = fr_dev(rfp);
rp = fc_frame_payload_get(rfp, sizeof(*rp));
@@ -2017,9 +2016,18 @@ static void fc_exch_els_rec(struct fc_frame *rfp)
rxid = ntohs(rp->rec_rx_id);
oxid = ntohs(rp->rec_ox_id);
- ep = fc_exch_lookup(lport,
- sid == fc_host_port_id(lport->host) ? oxid : rxid);
explan = ELS_EXPL_OXID_RXID;
+ if (sid == fc_host_port_id(lport->host))
+ xid = oxid;
+ else
+ xid = rxid;
+ if (xid == FC_XID_UNKNOWN) {
+ FC_LPORT_DBG(lport,
+ "REC request from %x: invalid rxid %x oxid %x\n",
+ sid, rxid, oxid);
+ goto reject;
+ }
+ ep = fc_exch_lookup(lport, xid);
if (!ep) {
FC_LPORT_DBG(lport,
"REC request from %x: rxid %x oxid %x not found\n",