Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: zfcp: fix request object use-after-free in send path causing wrong traces

When tracing instances where we open and close WKA ports, we also pass the
request-ID of the respective FSF command.

But after successfully sending the FSF command we must not use the
request-object anymore, as this might result in an use-after-free (see
"zfcp: fix request object use-after-free in send path causing seqno
errors" ).

To fix this add a new variable that caches the request-ID before sending
the request. This won't change during the hand-off to the FCP channel,
and so it's safe to trace this cached request-ID later, instead of using
the request object.

Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Fixes: d27a7cb91960 ("zfcp: trace on request for open and close of WKA port")
Cc: <stable@vger.kernel.org> #2.6.38+
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Benjamin Block and committed by
Martin K. Petersen
106d45f3 b76becde

+8 -2
+8 -2
drivers/s390/scsi/zfcp_fsf.c
··· 1627 1627 { 1628 1628 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1629 1629 struct zfcp_fsf_req *req; 1630 + unsigned long req_id = 0; 1630 1631 int retval = -EIO; 1631 1632 1632 1633 spin_lock_irq(&qdio->req_q_lock); ··· 1650 1649 hton24(req->qtcb->bottom.support.d_id, wka_port->d_id); 1651 1650 req->data = wka_port; 1652 1651 1652 + req_id = req->req_id; 1653 + 1653 1654 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); 1654 1655 retval = zfcp_fsf_req_send(req); 1655 1656 if (retval) ··· 1660 1657 out: 1661 1658 spin_unlock_irq(&qdio->req_q_lock); 1662 1659 if (!retval) 1663 - zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); 1660 + zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req_id); 1664 1661 return retval; 1665 1662 } 1666 1663 ··· 1686 1683 { 1687 1684 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1688 1685 struct zfcp_fsf_req *req; 1686 + unsigned long req_id = 0; 1689 1687 int retval = -EIO; 1690 1688 1691 1689 spin_lock_irq(&qdio->req_q_lock); ··· 1709 1705 req->data = wka_port; 1710 1706 req->qtcb->header.port_handle = wka_port->handle; 1711 1707 1708 + req_id = req->req_id; 1709 + 1712 1710 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); 1713 1711 retval = zfcp_fsf_req_send(req); 1714 1712 if (retval) ··· 1719 1713 out: 1720 1714 spin_unlock_irq(&qdio->req_q_lock); 1721 1715 if (!retval) 1722 - zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); 1716 + zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req_id); 1723 1717 return retval; 1724 1718 } 1725 1719