Messages in this thread |  | | Date | Sun, 3 Jul 2022 07:55:05 -0700 | Subject | Re: use-after-free in srpt_enable_tpg() | From | Bart Van Assche <> |
| |
On 7/2/22 19:11, Hillf Danton wrote: > On Sat, 2 Jul 2022 15:26:33 -0700 Bart Van Assche wrote: >> As long as a session is live the ch->qp pointer may be >> dereferenced. The sdev->pd pointer is stored in the pd member of struct >> ib_qp and hence may be dereferenced by any function that uses ch->qp. > > If it is still an issue after ib_dealloc_pd(sdev->pd) then it goes beyond the > aperture of my proposal and needs another fix. > > Hillf > > +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c > @@ -3235,6 +3235,8 @@ static void srpt_remove_one(struct ib_de > > ib_set_client_data(device, &srpt_client, NULL); > > + /* make sdev survive ib_dealloc_pd(sdev->pd); */ > + atomic_inc(&sdev->port_refcount); > /* > * Unregistering a target must happen after destroying sdev->cm_id > * such that no new SRP_LOGIN_REQ information units can arrive while > @@ -3250,6 +3252,9 @@ static void srpt_remove_one(struct ib_de > srpt_free_srq(sdev); > > ib_dealloc_pd(sdev->pd); > + > + if (0 == atomic_dec_return(&sdev->port_refcount)) > + kfree(sdev); > } > > static struct ib_client srpt_client = {
Do you perhaps want to combine the above patch with the previous patch? I don't think that any reference counting scheme can fix all use-after-free issues related to srpt_remove_one(). Immediately after srpt_remove_one() returns the caller of this function calls ib_device_put() and ib_client_put(). These functions free data structures that can be reached from the pointers that are stored in struct ib_qp. Holding a reference on struct ib_device as long as any session is live would allow to remove the while-loop from srpt_release_sport(). However, I'm not sure that would make a significant difference since there is a similar while-loop in one of the callers of srpt_remove_one() (disable_device() in the RDMA core).
Bart.
|  |