diff mbox series

[v3,13/14] IB/isert: Fix use after free during conn cleanup

Message ID 20230129234441.116310-14-michael.christie@oracle.com (mailing list archive)
State Deferred
Headers show
Series target: TMF and recovery fixes | expand

Commit Message

Mike Christie Jan. 29, 2023, 11:44 p.m. UTC
We can end up freeing a command too early during conn cleanup by doing:

1. Send iserts N 1MB writes.
2. Pull cable or down the port isert is using.
3. isert_wait_conn's call to isert_put_unsol_pending_cmds races
with a running isert_send_done -> isert_completion_put -> isert_put_cmd
where isert_put_unsol_pending_cmds sees the cmd on the conn_cmd_list
and it does a isert_put_cmd which will free the cmd. Then isert_send_done
is run and will access the freed command while doing it's normal command
completion:
isert_completion_put -> isert_put_cmd -> transport_generic_free_cmd

This patch has us increment write_data_done, so
isert_put_unsol_pending_cmds can correctly detect commands which will we
will not be calling isert_send_done for.

Fixes: 38a2d0d429f1 ("IB/isert: convert to the generic RDMA READ/WRITE
API")
[code written and suggested by]
Suggested-by: Sagi Grimberg <sagi@grimberg.me>

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/infiniband/ulp/isert/ib_isert.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Maurizio Lombardi Feb. 27, 2023, 3:10 p.m. UTC | #1
po 30. 1. 2023 v 0:45 odesílatel Mike Christie
<michael.christie@oracle.com> napsal:
>
> We can end up freeing a command too early during conn cleanup by doing:
>
> 1. Send iserts N 1MB writes.
> 2. Pull cable or down the port isert is using.
> 3. isert_wait_conn's call to isert_put_unsol_pending_cmds races
> with a running isert_send_done -> isert_completion_put -> isert_put_cmd
> where isert_put_unsol_pending_cmds sees the cmd on the conn_cmd_list
> and it does a isert_put_cmd which will free the cmd. Then isert_send_done
> is run and will access the freed command while doing it's normal command
> completion:
> isert_completion_put -> isert_put_cmd -> transport_generic_free_cmd
>
> This patch has us increment write_data_done, so
> isert_put_unsol_pending_cmds can correctly detect commands which will we
> will not be calling isert_send_done for.
>
> Fixes: 38a2d0d429f1 ("IB/isert: convert to the generic RDMA READ/WRITE
> API")
> [code written and suggested by]
> Suggested-by: Sagi Grimberg <sagi@grimberg.me>
>
> Signed-off-by: Mike Christie <michael.christie@oracle.com>
> ---
>  drivers/infiniband/ulp/isert/ib_isert.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
> index 516fa37494e1..a44da60352f6 100644
> --- a/drivers/infiniband/ulp/isert/ib_isert.c
> +++ b/drivers/infiniband/ulp/isert/ib_isert.c
> @@ -1636,7 +1636,7 @@ isert_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)
>         if (isert_prot_cmd(isert_conn, se_cmd))
>                 ret = isert_check_pi_status(se_cmd, isert_cmd->rw.reg->mr);
>         isert_rdma_rw_ctx_destroy(isert_cmd, isert_conn);
> -       cmd->write_data_done = 0;
> +       cmd->write_data_done = se_cmd->data_length; /* done fetching data */
>
>         isert_dbg("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd);
>         spin_lock_bh(&cmd->istate_lock);
> --
> 2.25.1
>

Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
diff mbox series

Patch

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 516fa37494e1..a44da60352f6 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -1636,7 +1636,7 @@  isert_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)
 	if (isert_prot_cmd(isert_conn, se_cmd))
 		ret = isert_check_pi_status(se_cmd, isert_cmd->rw.reg->mr);
 	isert_rdma_rw_ctx_destroy(isert_cmd, isert_conn);
-	cmd->write_data_done = 0;
+	cmd->write_data_done = se_cmd->data_length; /* done fetching data */
 
 	isert_dbg("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd);
 	spin_lock_bh(&cmd->istate_lock);