All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tyrel Datwyler <tyreld@linux.ibm.com>
To: Stefan Berger <stefanb@linux.ibm.com>,
	jarkko@kernel.org, peterhuewe@gmx.de,
	linux-integrity@vger.kernel.org
Cc: Korrapati.Likhitha@ibm.com, pavrampu@in.ibm.com,
	linux-kernel@vger.kernel.org, jgg@ziepe.ca,
	linux-security-module@vger.kernel.org, gcwilson@us.ibm.com,
	linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH] tpm: Fix kexec crash due to access to ops NULL pointer (powerpc)
Date: Mon, 20 Dec 2021 16:39:34 -0800	[thread overview]
Message-ID: <1052cd36-1b85-5d36-045f-5c5bf9f0fc4e@linux.ibm.com> (raw)
In-Reply-To: <20211212012804.1555661-1-stefanb@linux.ibm.com>

On 12/11/21 5:28 PM, Stefan Berger wrote:
> Fix the following crash on kexec by checking chip->ops for a NULL pointer
> in tpm_chip_start() and returning an error code if this is the case.
> 
> BUG: Kernel NULL pointer dereference on read at 0x00000060
> Faulting instruction address: 0xc00000000099a06c
> Oops: Kernel access of bad area, sig: 11 [#1]
> ...
> NIP [c00000000099a06c] tpm_chip_start+0x2c/0x140
>  LR [c00000000099a808] tpm_chip_unregister+0x108/0x170
> Call Trace:
> [c0000000188bfa00] [c000000002b03930] fw_devlink_strict+0x0/0x8 (unreliable)
> [c0000000188bfa30] [c00000000099a808] tpm_chip_unregister+0x108/0x170
> [c0000000188bfa70] [c0000000009a3874] tpm_ibmvtpm_remove+0x34/0x130
> [c0000000188bfae0] [c000000000110dbc] vio_bus_remove+0x5c/0xb0
> [c0000000188bfb20] [c0000000009bc154] device_shutdown+0x1d4/0x3a8
> [c0000000188bfbc0] [c000000000196e14] kernel_restart_prepare+0x54/0x70
> 
> The referenced patch below introduced a function to shut down the VIO bus.
> The bus shutdown now calls tpm_del_char_device (via tpm_chip_unregister)
> after a call to tpm_class_shutdown, which already set chip->ops to NULL.
> The crash occurrs when tpm_del_char_device calls tpm_chip_start with the
> chip->ops NULL pointer.

It was unclear to me at first, but IIUC the problem is the ibmvtpm device
receives two shutdown calls, the first is a class shutdown call for TPM devices,
followed by a bus shutdown call for VIO devices.

It appears that the class shutdown routines are meant to be a pre-shutdown
routine as they are defined as class->shutdown_pre(), and it is clearly allowed
to call class->shutdown_pre() followed by one of but not both of the following
bus->shutdown() or driver->shutdown(). Even tpm_class_shutdown() mentions in the
function comment that bus/device shutdown to follow.

> 
> Fixes: 39d0099f9439 ("powerpc/pseries: Add shutdown() to vio_driver and vio_bus")

This patch left implementing each vio driver shutdown routine as an exercise for
the respective maintainers, and instead just big hammers anything that doesn't
have a shutdown routine by calling the driver->remove().

If tpm_class_shutdown() quiecses ibmvtpm enough implementing a no-op
ibmvtpm->shutdown() with a comment saying so suffices.

However, the generic TPM code is still introducing a bug that an attempt to call
tpm_chip_unregister() after tpm_class_shutdown() will crash as mentioned above.

> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  drivers/char/tpm/tpm-chip.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index ddaeceb7e109..cca1bde296ee 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -101,6 +101,9 @@ int tpm_chip_start(struct tpm_chip *chip)
>  {
>  	int ret;
> 
> +	if (!chip->ops)
> +		return -EINVAL;
> +

I wonder if a better fix would to have tpm_del_char_device() check for valid
chip->ops and call tpm_class_shutdown() when the ops are still valid. Calling
tpm_class_shutdown() allows for some code deduplication in tpm_del_char_device().

-Tyrel

>  	tpm_clk_enable(chip);
> 
>  	if (chip->locality == -1) {
> 


  parent reply	other threads:[~2021-12-21  0:39 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-12  1:28 [PATCH] tpm: Fix kexec crash due to access to ops NULL pointer (powerpc) Stefan Berger
2021-12-12  1:28 ` Stefan Berger
2021-12-20  5:17 ` Sachin Sant
2021-12-20  5:17   ` Sachin Sant
2021-12-21  0:39 ` Tyrel Datwyler [this message]
2021-12-21  1:05   ` Stefan Berger
2021-12-21  1:13     ` Jason Gunthorpe
2021-12-21  1:13       ` Jason Gunthorpe
2021-12-21  1:31       ` Stefan Berger
2021-12-21  1:31         ` Stefan Berger
2021-12-21  1:37         ` Tyrel Datwyler
2021-12-21  1:37           ` Tyrel Datwyler
2021-12-21  1:34     ` Tyrel Datwyler
2021-12-21  8:47 ` Jarkko Sakkinen
2021-12-21  8:47   ` Jarkko Sakkinen
2021-12-21 14:01   ` Stefan Berger
2021-12-21 14:01     ` Stefan Berger
2021-12-21 14:17     ` Stefan Berger
2021-12-21 14:17       ` Stefan Berger
2021-12-29  0:10     ` Jarkko Sakkinen
2021-12-29  0:10       ` Jarkko Sakkinen

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=1052cd36-1b85-5d36-045f-5c5bf9f0fc4e@linux.ibm.com \
    --to=tyreld@linux.ibm.com \
    --cc=Korrapati.Likhitha@ibm.com \
    --cc=gcwilson@us.ibm.com \
    --cc=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=pavrampu@in.ibm.com \
    --cc=peterhuewe@gmx.de \
    --cc=stefanb@linux.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.