[<prev] [next>] [day] [month] [year] [list]
Message-ID: <19f203e5-e965-23bd-401b-0ae8d9a73a5d@acm.org>
Date: Sun, 3 Jul 2022 07:55:05 -0700
From: Bart Van Assche <bvanassche@....org>
To: Hillf Danton <hdanton@...a.com>
Cc: Mike Christie <michael.christie@...cle.com>,
"lizhijian@...itsu.com" <lizhijian@...itsu.com>,
Jason Gunthorpe <jgg@...pe.ca>,
Leon Romanovsky <leon@...nel.org>,
"linux-rdma@...r.kernel.org" <linux-rdma@...r.kernel.org>,
"target-devel@...r.kernel.org" <target-devel@...r.kernel.org>,
open list <linux-kernel@...r.kernel.org>
Subject: Re: use-after-free in srpt_enable_tpg()
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.
Powered by blists - more mailing lists