Commit a3c27880 authored by Bernard Metzler's avatar Bernard Metzler Committed by Leon Romanovsky
Browse files

RDMA/siw: Fix QP destroy to wait for all references dropped.



Delay QP destroy completion until all siw references to QP are
dropped. The calling RDMA core will free QP structure after
successful return from siw_qp_destroy() call, so siw must not
hold any remaining reference to the QP upon return.
A use-after-free was encountered in xfstest generic/460, while
testing NFSoRDMA. Here, after a TCP connection drop by peer,
the triggered siw_cm_work_handler got delayed until after
QP destroy call, referencing a QP which has already freed.

Fixes: 303ae1cd ("rdma/siw: application interface")
Reported-by: default avatarOlga Kornievskaia <kolga@netapp.com>
Signed-off-by: default avatarBernard Metzler <bmt@zurich.ibm.com>
Link: https://lore.kernel.org/r/20220920082503.224189-1-bmt@zurich.ibm.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 75420985
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -418,6 +418,7 @@ struct siw_qp {
	struct ib_qp base_qp;
	struct siw_device *sdev;
	struct kref ref;
	struct completion qp_free;
	struct list_head devq;
	int tx_cpu;
	struct siw_qp_attrs attrs;
+1 −1
Original line number Diff line number Diff line
@@ -1342,6 +1342,6 @@ void siw_free_qp(struct kref *ref)
	vfree(qp->orq);

	siw_put_tx_cpu(qp->tx_cpu);

	complete(&qp->qp_free);
	atomic_dec(&sdev->num_qp);
}
+3 −0
Original line number Diff line number Diff line
@@ -480,6 +480,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
	list_add_tail(&qp->devq, &sdev->qp_list);
	spin_unlock_irqrestore(&sdev->lock, flags);

	init_completion(&qp->qp_free);

	return 0;

err_out_xa:
@@ -624,6 +626,7 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
	qp->scq = qp->rcq = NULL;

	siw_qp_put(qp);
	wait_for_completion(&qp->qp_free);

	return 0;
}