aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Maier <maier@linux.vnet.ibm.com>2017-02-08 09:34:22 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-14 18:25:39 -0500
commite19722449e736d4811f24f68e3a36d4d8e5d429e (patch)
treef36df8a9f45ad68a2a3d35dc05ff97d56048efe8
parent1cf897fcc5a99e5ecf2f6fb12adec6d485a17e14 (diff)
scsi: zfcp: fix use-after-free by not tracing WKA port open/close on failed send
commit 2dfa6688aafdc3f74efeb1cf05fb871465d67f79 upstream. Dan Carpenter kindly reported: <quote> The patch d27a7cb91960: "zfcp: trace on request for open and close of WKA port" from Aug 10, 2016, leads to the following static checker warning: drivers/s390/scsi/zfcp_fsf.c:1615 zfcp_fsf_open_wka_port() warn: 'req' was already freed. drivers/s390/scsi/zfcp_fsf.c 1609 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); 1610 retval = zfcp_fsf_req_send(req); 1611 if (retval) 1612 zfcp_fsf_req_free(req); ^^^ Freed. 1613 out: 1614 spin_unlock_irq(&qdio->req_q_lock); 1615 if (req && !IS_ERR(req)) 1616 zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); ^^^^^^^^^^^ Use after free. 1617 return retval; 1618 } Same thing for zfcp_fsf_close_wka_port() as well. </quote> Rather than relying on req being NULL (or ERR_PTR) for all cases where we don't want to trace or should not trace, simply check retval which is unconditionally initialized with -EIO != 0 and it can only become 0 on successful retval = zfcp_fsf_req_send(req). With that we can also remove the then again unnecessary unconditional initialization of req which was introduced with that earlier commit. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Suggested-by: Benjamin Block <bblock@linux.vnet.ibm.com> Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com> Fixes: d27a7cb91960 ("zfcp: trace on request for open and close of WKA port") Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com> Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 75f820ca17b7..27ff38f839fc 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1583,7 +1583,7 @@ out:
1583int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) 1583int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
1584{ 1584{
1585 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1585 struct zfcp_qdio *qdio = wka_port->adapter->qdio;
1586 struct zfcp_fsf_req *req = NULL; 1586 struct zfcp_fsf_req *req;
1587 int retval = -EIO; 1587 int retval = -EIO;
1588 1588
1589 spin_lock_irq(&qdio->req_q_lock); 1589 spin_lock_irq(&qdio->req_q_lock);
@@ -1612,7 +1612,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
1612 zfcp_fsf_req_free(req); 1612 zfcp_fsf_req_free(req);
1613out: 1613out:
1614 spin_unlock_irq(&qdio->req_q_lock); 1614 spin_unlock_irq(&qdio->req_q_lock);
1615 if (req && !IS_ERR(req)) 1615 if (!retval)
1616 zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); 1616 zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
1617 return retval; 1617 return retval;
1618} 1618}
@@ -1638,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
1638int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) 1638int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
1639{ 1639{
1640 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1640 struct zfcp_qdio *qdio = wka_port->adapter->qdio;
1641 struct zfcp_fsf_req *req = NULL; 1641 struct zfcp_fsf_req *req;
1642 int retval = -EIO; 1642 int retval = -EIO;
1643 1643
1644 spin_lock_irq(&qdio->req_q_lock); 1644 spin_lock_irq(&qdio->req_q_lock);
@@ -1667,7 +1667,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
1667 zfcp_fsf_req_free(req); 1667 zfcp_fsf_req_free(req);
1668out: 1668out:
1669 spin_unlock_irq(&qdio->req_q_lock); 1669 spin_unlock_irq(&qdio->req_q_lock);
1670 if (req && !IS_ERR(req)) 1670 if (!retval)
1671 zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); 1671 zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
1672 return retval; 1672 return retval;
1673} 1673}