On Fri, Feb 05, 2021 at 03:55:09PM +0100, Lino Sanfilippo wrote: > Hi, > > On 05.02.21 14:05, Jason Gunthorpe wrote: > > >> > >> Commit fdc915f7f719 ("tpm: expose spaces via a device link /dev/tpmrm<n>") > >> already introduced function tpm_devs_release() to release the extra > >> reference but did not implement the required put on chip->devs that results > >> in the call of this function. > > > > Seems wonky, the devs is just supposed to be a side thing, nothing > > should be using it as a primary reference count for a tpm. > > > > The bug here is only that tpm_common_open() did not get a kref on the > > chip before putting it in priv and linking it to the fd. See the > > comment before tpm_try_get_ops() indicating the caller must already > > have taken care to ensure the chip is valid. > > > > This should be all you need to fix the oops: > > > > diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c > > index 1784530b8387bb..1b738dca7fffb5 100644 > > +++ b/drivers/char/tpm/tpm-dev-common.c > > @@ -105,6 +105,7 @@ static void tpm_timeout_work(struct work_struct *work) > > void tpm_common_open(struct file *file, struct tpm_chip *chip, > > struct file_priv *priv, struct tpm_space *space) > > { > > + get_device(&priv->chip.dev); > > priv->chip = chip; > > priv->space = space; > > priv->response_read = true; > > This is racy, isnt it? The time between we open the file and we want to grab the > reference in common_open() the chip can already be unregistered and freed. No, the cdev layer holds the refcount on the device while open is being called. Jason