From: Mike Christie Date: Mon, 4 Oct 2021 21:06:08 +0000 (-0500) Subject: scsi: iscsi: Fix iscsi_task use after free X-Git-Tag: baikal/aarch64/sdk6.1~5596^2 X-Git-Url: https://git.baikalelectronics.ru/sdk/?a=commitdiff_plain;h=446369f7a50fcfd64f909faa64cd72acff25dbd0;p=kernel.git scsi: iscsi: Fix iscsi_task use after free Commit add28fd1450f ("scsi: iscsi: Have abort handler get ref to conn") added iscsi_get_conn()/iscsi_put_conn() calls during abort handling but then also changed the handling of the case where we detect an already completed task where we now end up doing a goto to the common put/cleanup code. This results in a iscsi_task use after free, because the common cleanup code will do a put on the iscsi_task. This reverts the goto and moves the iscsi_get_conn() to after we've checked if the iscsi_task is valid. Link: https://lore.kernel.org/r/20211004210608.9962-1-michael.christie@oracle.com Fixes: add28fd1450f ("scsi: iscsi: Have abort handler get ref to conn") Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4683c183e9d41..5bc91d34df634 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) return FAILED; } - conn = session->leadconn; - iscsi_get_conn(conn->cls_conn); - conn->eh_abort_cnt++; - age = session->age; - spin_lock(&session->back_lock); task = (struct iscsi_task *)sc->SCp.ptr; if (!task || !task->sc) { @@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); spin_unlock(&session->back_lock); - goto success; + spin_unlock_bh(&session->frwd_lock); + mutex_unlock(&session->eh_mutex); + return SUCCESS; } + + conn = session->leadconn; + iscsi_get_conn(conn->cls_conn); + conn->eh_abort_cnt++; + age = session->age; + ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt); __iscsi_get_task(task); spin_unlock(&session->back_lock);