Skip to content

Commit

Permalink
scsi: iscsi: Fix endpoint reuse regression
Browse files Browse the repository at this point in the history
This patch fixes a bug where when using iSCSI offload we can free an
endpoint while userspace still thinks it's active. That then causes the
endpoint ID to be reused for a new connection's endpoint while userspace
still thinks the ID is for the original connection. Userspace will then end
up disconnecting a running connection's endpoint or trying to bind to
another connection's endpoint.

This bug is a regression added in:

Commit 23d6fef ("scsi: iscsi: Fix in-kernel conn failure handling")

where we added a in kernel ep_disconnect call to fix a bug in:

Commit 0ab7104 ("scsi: iscsi: Perform connection failure entirely in
kernel space")

where we would call stop_conn without having done ep_disconnect. This early
ep_disconnect call will then free the endpoint and it's ID while userspace
still thinks the ID is valid.

Fix the early release of the ID by having the in kernel recovery code keep
a reference to the endpoint until userspace has called into the kernel to
finish cleaning up the endpoint/connection. It requires the previous commit
"scsi: iscsi: Release endpoint ID when its freed" which moved the freeing
of the ID until when the endpoint is released.

Link: https://lore.kernel.org/r/20220408001314.5014-5-michael.christie@oracle.com
Fixes: 23d6fef ("scsi: iscsi: Fix in-kernel conn failure handling")
Tested-by: Manish Rangankar <mrangankar@marvell.com>
Reviewed-by: Lee Duncan <lduncan@suse.com>
Reviewed-by: Chris Leech <cleech@redhat.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Mike Christie authored and Martin K. Petersen committed Apr 12, 2022
1 parent 3c6ae37 commit 0aadafb
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,11 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
mutex_unlock(&conn->ep_mutex);

flush_work(&conn->cleanup_work);

/*
* Userspace is now done with the EP so we can release the ref
* iscsi_cleanup_conn_work_fn took.
*/
iscsi_put_endpoint(ep);
mutex_lock(&conn->ep_mutex);
}
}
Expand Down Expand Up @@ -2322,6 +2326,12 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
return;
}

/*
* Get a ref to the ep, so we don't release its ID until after
* userspace is done referencing it in iscsi_if_disconnect_bound_ep.
*/
if (conn->ep)
get_device(&conn->ep->dev);
iscsi_ep_disconnect(conn, false);

if (system_state != SYSTEM_RUNNING) {
Expand Down

0 comments on commit 0aadafb

Please sign in to comment.