Jason Gunthorpe <[email protected]> wrote on 02/12/2016 
04:15:38 PM:

> From: Jason Gunthorpe <[email protected]>
> To: Stefan Berger/Watson/IBM@IBMUS
> Cc: [email protected], [email protected], Jarkko Sakkinen 
> <[email protected]>, [email protected]
> Date: 02/12/2016 04:15 PM
> Subject: Re: [tpmdd-devel] [PATCH v5 4/5] Initialize TPM and get 
> durations and timeouts
> 
> On Fri, Feb 12, 2016 at 03:44:14PM -0500, Stefan Berger wrote:
> >    What I observed is that both tpm_chip and vtpm_dev structures are 
freed
> >    once the last one of two sides (/dev/tpmX or server side file
> >    descriptor) closes.
> 
> Hmmm...
> 
> I don't see how that can happen. Looking at the tpm cdev, it is

Well, following my tests, it does happen.

> continues to exist even after tpm_unregister returns (cdev_del does
> not force close existing opens). Certainly the kAPI (ie
> tpm_chip_find_get) will continue to use the chip without blocking
> tpm_unregister.
> 
> I see no mechanism for the cdev/kAPI to continue to hold a kref on the
> vtpm struct.
> 
> The obvious one would be because the vtpm struct is a parent of the
> chip, but that kref is let go during device_del.
> 
> So, we have a situation where tpm_unregister can return, release the
> kref on the vtpm and still have outstanding users, which will result
> in a use after-free.

Maybe you should give it a try ... I don't see these problems and any 
change seems like ill-fixing it. What will be accessed after 
tpm_unregister? The only case we have tpm_unregister is here:

static void vtpm_delete_device_pair(struct vtpm_dev *vtpm_dev)
{
        tpm_chip_unregister(vtpm_dev->chip);

        vtpm_fops_undo_open(vtpm_dev);

        vtpm_delete_vtpm_dev(vtpm_dev);
}

followed by:

static inline void vtpm_delete_vtpm_dev(struct vtpm_dev *vtpm_dev)
{
        put_device(&vtpm_dev->chip->dev); /* frees chip */
        device_unregister(&vtpm_dev->dev); /* does put_device */
}

I don't see a problem with that.

> 
> [BTW, your lastest vtpm on github still has a problem with error
>  unwind. Move the put_device(&vtpm_dev->chip->dev);  from
>  vtpm_delete_vtpm_dev() and put it in vtpm_dev_release() with a NULL
>  test.

I tested all the error paths. The vtpm_delete_vtpm_dev is the counter-part 
to vtpm_create_vtpm_dev and only ever gets called if vtpm_create_vtpm_dev 
ran successfully and is the function to call to unwind 
vtpm_create_vtpm_dev. So if we unwind there in reverse order then we 
should be ok. If not, why not ?

> 
>  The put_device is missing after the tpm_chip_unregister call, the
>  above is the safest way to fix it.

No, it's the vtpm_delete_vtpm_dev function that unwinds it. I tested this 
and structures get freed properly.

> 
>  This is why you shouldn't wrapper put_device, anything but naked
>  put_device is probably wrong]
> 
> [Also, err_kfree should not exist in vtpm_create_vtpm_dev, always
>  put_device after device_initialize returns, the comment near the 
device_add
>  is wrong, it is using the get_device done implicitly by
>  device_initialize]

Fixed.
> 
> [Don't forget to error check dev_set_name]

Fixed. Looks like 80% of the drivers don't check here.

   Stefan
> 
> Jason
> 


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
tpmdd-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

Reply via email to