Commit e17fa5c9 authored by Krishnamraju Eraparaju's avatar Krishnamraju Eraparaju Committed by Doug Ledford

RDMA/siw: free siw_base_qp in kref release routine

As siw_free_qp() is the last routine to access 'siw_base_qp' structure,
freeing this structure early in siw_destroy_qp() could cause
touch-after-free issue.
Hence, moved kfree(siw_base_qp) from siw_destroy_qp() to siw_free_qp().

Fixes: 303ae1cd ("rdma/siw: application interface")
Signed-off-by: default avatarKrishnamraju Eraparaju <krishna2@chelsio.com>
Link: https://lore.kernel.org/r/20191007104229.29412-1-krishna2@chelsio.comSigned-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 54102dd4
...@@ -1312,6 +1312,7 @@ int siw_qp_add(struct siw_device *sdev, struct siw_qp *qp) ...@@ -1312,6 +1312,7 @@ int siw_qp_add(struct siw_device *sdev, struct siw_qp *qp)
void siw_free_qp(struct kref *ref) void siw_free_qp(struct kref *ref)
{ {
struct siw_qp *found, *qp = container_of(ref, struct siw_qp, ref); struct siw_qp *found, *qp = container_of(ref, struct siw_qp, ref);
struct siw_base_qp *siw_base_qp = to_siw_base_qp(qp->ib_qp);
struct siw_device *sdev = qp->sdev; struct siw_device *sdev = qp->sdev;
unsigned long flags; unsigned long flags;
...@@ -1334,4 +1335,5 @@ void siw_free_qp(struct kref *ref) ...@@ -1334,4 +1335,5 @@ void siw_free_qp(struct kref *ref)
atomic_dec(&sdev->num_qp); atomic_dec(&sdev->num_qp);
siw_dbg_qp(qp, "free QP\n"); siw_dbg_qp(qp, "free QP\n");
kfree_rcu(qp, rcu); kfree_rcu(qp, rcu);
kfree(siw_base_qp);
} }
...@@ -604,7 +604,6 @@ int siw_verbs_modify_qp(struct ib_qp *base_qp, struct ib_qp_attr *attr, ...@@ -604,7 +604,6 @@ int siw_verbs_modify_qp(struct ib_qp *base_qp, struct ib_qp_attr *attr,
int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
{ {
struct siw_qp *qp = to_siw_qp(base_qp); struct siw_qp *qp = to_siw_qp(base_qp);
struct siw_base_qp *siw_base_qp = to_siw_base_qp(base_qp);
struct siw_ucontext *uctx = struct siw_ucontext *uctx =
rdma_udata_to_drv_context(udata, struct siw_ucontext, rdma_udata_to_drv_context(udata, struct siw_ucontext,
base_ucontext); base_ucontext);
...@@ -641,7 +640,6 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) ...@@ -641,7 +640,6 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
qp->scq = qp->rcq = NULL; qp->scq = qp->rcq = NULL;
siw_qp_put(qp); siw_qp_put(qp);
kfree(siw_base_qp);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment