Re: [PATCH] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept

Bernard Metzler <[email protected]>
Newsgroups org.kernel.vger.linux-rdma
Message-ID <[email protected]>
On 25.08.2026 15:09, Guoqing Jiang wrote:
> We need to clear qp and cep before release state_lock as siw_qp_llp_closeo
> and siw_qp_modify->siw_qp_llp_close did.
> 
> Otherwise if siw_qp_modify() fails in siw_accept(), the QP's state_lock
> is released before the error path cleanup. A concurrent ibv_modify_qp()
> transitioning the QP to ERROR can race in this window:
> 
>    siw_accept()                       ibv_modify_qp(ERROR)
>    ----------------------             ----------------------
>    siw_qp_modify() fails
>    up_write(&qp->state_lock)
>                                       down_write(&qp->state_lock)
>                                       nextstate_from_idle():
> 				     if (qp->cep)
>                                         siw_cep_put(qp->cep) <- frees cep
>                                         qp->cep = NULL
>    goto error
>      cep->qp = NULL                   <- UAF
> 
> Clear qp->cep and cep->qp, and drop the association reference taken by
> siw_cep_get(), all under the write lock held from the initial
> down_write(&qp->state_lock). Thread B therefore sees qp->cep == NULL,
> skips its own put, and cannot free the cep before siw_accept() is done
> with it.
> 
> Reported-by: Shuangpeng Bai <[email protected]>
> Link: https://lore.kernel.org/linux-rdma/[email protected]/T/#m5876c1ff2de8686a9a1173b8f1aa0ff5363a785c
> Signed-off-by: Guoqing Jiang <[email protected]>
> ---
>   drivers/infiniband/sw/siw/siw_cm.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
> index 0245b25e7271..1573f2e888b2 100644
> --- a/drivers/infiniband/sw/siw/siw_cm.c
> +++ b/drivers/infiniband/sw/siw/siw_cm.c
> @@ -1719,9 +1719,13 @@ int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
>   			   SIW_QP_ATTR_STATE | SIW_QP_ATTR_LLP_HANDLE |
>   				   SIW_QP_ATTR_ORD | SIW_QP_ATTR_IRD |
>   				   SIW_QP_ATTR_MPA);
> +	if (rv) {
> +		cep->qp = NULL;
This can better be omitted since done in error_unlock path
anyway and is redundant otherwise. It would also better
retain the logic of calling siw_qp_put(qp) right after
clearing cep's reference to the qp, as done in error path.

Thank you!
Bernard.> +		qp->cep = NULL;
> +		siw_cep_put(cep);
> +		goto error_unlock;
> +	}
>   	up_write(&qp->state_lock);
> -	if (rv)
> -		goto error;
>   
>   	siw_dbg_cep(cep, "[QP %u]: send mpa reply, %d byte pdata\n",
>   		    qp_id(qp), params->private_data_len);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.