All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko@kernel.org>
To: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Cc: peterhuewe@gmx.de, jgg@ziepe.ca, stefanb@linux.vnet.ibm.com,
	linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org,
	p.rosenberger@kunbus.com,
	Lino Sanfilippo <l.sanfilippo@kunbus.com>
Subject: Re: [PATCH 2/4] tpm: fix reference counting for struct tpm_chip
Date: Sun, 17 Jan 2021 20:11:56 +0200	[thread overview]
Message-ID: <YAR97EMb47QM2ZkO@kernel.org> (raw)
In-Reply-To: <1610760161-21982-3-git-send-email-LinoSanfilippo@gmx.de>

On Sat, Jan 16, 2021 at 02:22:39AM +0100, Lino Sanfilippo wrote:
> From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
> 
> Commit 8979b02aaf1d ("tpm: Fix reference count to main device") tried to
> fix a reference count issue which prevented the tpm_chip structure from
> being freed in case that no TPM2 was used. The fix was to only get an extra
> reference for chip->dev in case of TPM2 which is indicated by the
> TPM_CHIP_FLAG_TPM2 flag.
> Unfortunately this flag is never set, and thus the extra reference is not
> taken even in the TPM2 case. This results in a refcount underflow in case
> that the device file /dev/tpmrm* is used to write data after the tpm_chip
> has been unregistered (e.g if the /dev/tpmrm* file has been opened before
> and not yet closed at the time the chip was unregistered.)
> 
> Also the error path (label "out") in tpm_chip_alloc() results in such an
> underflow, since the dev reference is put twice (one time directly and the
> second time by the call of tpm_devs_release() due to the put of
> chip->devs).
> 
> Fix the described issues by taking the extra reference unconditionally and
> installing an additional resource management action handler which puts
> chip->devs. Releasing chip->devs eventually results in the call of
> tpm_devs_release() which then releases the extra reference to chip->dev.
> 
> Since we now actually take that extra reference, adjust users of
> tpm_chip_alloc() like VTPM proxy and FTPM tee to release it indirectly by
> putting the reference of chip->devs.
> 
> Fixes: 8979b02aaf1d ("tpm: Fix reference count to main device")
> Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
> ---
>  drivers/char/tpm/tpm-chip.c       | 11 +++++++++--
>  drivers/char/tpm/tpm_ftpm_tee.c   |  2 ++
>  drivers/char/tpm/tpm_vtpm_proxy.c |  1 +
>  3 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index e242d2e..596824c 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -360,8 +360,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
>  	 * while cdevs is in use.  The corresponding put
>  	 * is in the tpm_devs_release (TPM2 only)
>  	 */
> -	if (chip->flags & TPM_CHIP_FLAG_TPM2)
> -		get_device(&chip->dev);
> +	get_device(&chip->dev);
>  
>  	if (chip->dev_num == 0)
>  		chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
> @@ -425,12 +424,20 @@ struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
>  	if (rc)
>  		goto put_dev;
>  
> +	rc = devm_add_action_or_reset(pdev,
> +				      (void (*)(void *)) put_device,
> +				      &chip->devs);
> +	if (rc)
> +		goto put_devs;
> +
>  	dev_set_drvdata(pdev, chip);
>  
>  	return chip;
>  
>  put_dev:
>  	put_device(&chip->dev);
> +put_devs:
> +	put_device(&chip->devs);
>  	return ERR_PTR(rc);
>  }
>  EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
> diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c
> index 2ccdf8a..82858c2 100644
> --- a/drivers/char/tpm/tpm_ftpm_tee.c
> +++ b/drivers/char/tpm/tpm_ftpm_tee.c
> @@ -286,6 +286,7 @@ static int ftpm_tee_probe(struct device *dev)
>  
>  out_chip:
>  	put_device(&pvt_data->chip->dev);
> +	put_device(&pvt_data->chip->devs);
>  out_chip_alloc:
>  	tee_shm_free(pvt_data->shm);
>  out_shm_alloc:
> @@ -318,6 +319,7 @@ static int ftpm_tee_remove(struct device *dev)
>  	tpm_chip_unregister(pvt_data->chip);
>  
>  	/* frees chip */
> +	put_device(&pvt_data->chip->devs);
>  	put_device(&pvt_data->chip->dev);
>  
>  	/* Free the shared memory pool */
> diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
> index 91c772e3..97b60f8 100644
> --- a/drivers/char/tpm/tpm_vtpm_proxy.c
> +++ b/drivers/char/tpm/tpm_vtpm_proxy.c
> @@ -520,6 +520,7 @@ static struct proxy_dev *vtpm_proxy_create_proxy_dev(void)
>   */
>  static inline void vtpm_proxy_delete_proxy_dev(struct proxy_dev *proxy_dev)
>  {
> +	put_device(&proxy_dev->chip->devs);
>  	put_device(&proxy_dev->chip->dev); /* frees chip */
>  	kfree(proxy_dev);
>  }
> -- 
> 2.7.4
> 

NAK

/Jarkko

  reply	other threads:[~2021-01-17 18:13 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-16  1:22 [PATCH 0/4] TPM fixes Lino Sanfilippo
2021-01-16  1:22 ` [PATCH 1/4] tpm: in case of error properly cleanup in tpmm_chip_alloc Lino Sanfilippo
2021-01-17 18:08   ` Jarkko Sakkinen
2021-01-16  1:22 ` [PATCH 2/4] tpm: fix reference counting for struct tpm_chip Lino Sanfilippo
2021-01-17 18:11   ` Jarkko Sakkinen [this message]
2021-01-16  1:22 ` [PATCH 3/4] tpm: in tpm2_del_space check if ops pointer is still valid Lino Sanfilippo
2021-01-17 18:13   ` Jarkko Sakkinen
2021-01-24 16:47     ` Lino Sanfilippo
2021-01-26 15:29       ` Jarkko Sakkinen
2021-01-27 15:14         ` Lino Sanfilippo
2021-01-16  1:22 ` [PATCH 4/4] tpm: Provide a function tpm_chip_free() to free tpm chips Lino Sanfilippo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YAR97EMb47QM2ZkO@kernel.org \
    --to=jarkko@kernel.org \
    --cc=LinoSanfilippo@gmx.de \
    --cc=jgg@ziepe.ca \
    --cc=l.sanfilippo@kunbus.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.rosenberger@kunbus.com \
    --cc=peterhuewe@gmx.de \
    --cc=stefanb@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.