[v4,1/2] tpm: Unify the send callback behaviour
diff mbox series

Message ID 20190208180857.12330-2-jarkko.sakkinen@linux.intel.com
State New
Headers show
Series
  • tpm: Unify send() callbacks
Related show

Commit Message

Jarkko Sakkinen Feb. 8, 2019, 6:08 p.m. UTC
The send() callback should never return length as it does not in every
driver except tpm_crb in the success case. The reason is that the main
transmit functionality only cares about whether the transmit was
successful or not and ignores the count completely.

Cc: stable@vger.kernel.org
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
 drivers/char/tpm/tpm_atmel.c         | 2 +-
 drivers/char/tpm/tpm_i2c_atmel.c     | 6 +++++-
 drivers/char/tpm/tpm_i2c_infineon.c  | 2 +-
 drivers/char/tpm/tpm_i2c_nuvoton.c   | 2 +-
 drivers/char/tpm/tpm_ibmvtpm.c       | 8 ++++----
 drivers/char/tpm/tpm_infineon.c      | 2 +-
 drivers/char/tpm/tpm_nsc.c           | 2 +-
 drivers/char/tpm/tpm_tis_core.c      | 2 +-
 drivers/char/tpm/tpm_vtpm_proxy.c    | 3 +--
 drivers/char/tpm/xen-tpmfront.c      | 2 +-
 11 files changed, 18 insertions(+), 15 deletions(-)

Comments

Stefan Berger Feb. 8, 2019, 6:12 p.m. UTC | #1
On 2/8/19 1:08 PM, Jarkko Sakkinen wrote:
> The send() callback should never return length as it does not in every
> driver except tpm_crb in the success case. The reason is that the main
> transmit functionality only cares about whether the transmit was
> successful or not and ignores the count completely.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

Let me know when you put it into your tree, I'll give it a spin while I 
am at it. :-)
Jarkko Sakkinen Feb. 8, 2019, 7 p.m. UTC | #2
On Fri, Feb 08, 2019 at 01:12:34PM -0500, Stefan Berger wrote:
> On 2/8/19 1:08 PM, Jarkko Sakkinen wrote:
> > The send() callback should never return length as it does not in every
> > driver except tpm_crb in the success case. The reason is that the main
> > transmit functionality only cares about whether the transmit was
> > successful or not and ignores the count completely.
> > 
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> 
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> 
> Let me know when you put it into your tree, I'll give it a spin while I am
> at it. :-)

Thank you Stefan! I also add your suggested-by to the first commit
because you pointed out the problem.

It all looks now legit, but just in case I'll add a check for the return
value to tpm_try_transmit() and a warning if it is not zero in the
success case (and after that zeroing of rc).

That check can be removed when I do v5.3 pull request. That should
enough window to catch any potential issues and check will ensure that
kernel won't fail even there was something forgotten.

Alexander, I'll push this version now to the master and next with the
additional check described in this commit, but will add your tags
after you have time to test.

Thanks alot!

/Jarkko
Jarkko Sakkinen Feb. 8, 2019, 7:17 p.m. UTC | #3
On Fri, Feb 08, 2019 at 09:00:57PM +0200, Jarkko Sakkinen wrote:
> It all looks now legit, but just in case I'll add a check for the return
> value to tpm_try_transmit() and a warning if it is not zero in the
> success case (and after that zeroing of rc).

Now the commits are applied both master and next, and these are
the checks for send():

rc = chip->ops->send(chip, buf, count);
if (rc < 0) {
	if (rc != -EPIPE)
		dev_err(&chip->dev,
			"%s: send(): error %d\n", __func__, rc);
	return rc;
}

/* A sanity check. send() should just return zero on success e.g.
 * not the command length.
 */
if (rc > 0) {
	dev_warn(&chip->dev,
		 "%s: send(): invalid value %d\n", __func__, rc);
	rc = 0;
}

Should be fairly safe play now.

/Jarkko
Stefan Berger Feb. 8, 2019, 7:27 p.m. UTC | #4
On 2/8/19 2:17 PM, Jarkko Sakkinen wrote:
>
>   */
> if (rc > 0) {
> 	dev_warn(&chip->dev,
> 		 "%s: send(): invalid value %d\n", __func__, rc);
> 	rc = 0;
> }
>
> Should be fairly safe play now.

Unfortuantely it isn't. You seemed to have lost the 
EXPORT_SYMBOL_GPL(tpm_chip_start/stop) and the tpm_chip_start/stop 
around the tpm2_shutdown()...


>
> /Jarkko
>
Jarkko Sakkinen Feb. 8, 2019, 8:23 p.m. UTC | #5
On Fri, Feb 08, 2019 at 02:27:31PM -0500, Stefan Berger wrote:
> On 2/8/19 2:17 PM, Jarkko Sakkinen wrote:
> > 
> >   */
> > if (rc > 0) {
> > 	dev_warn(&chip->dev,
> > 		 "%s: send(): invalid value %d\n", __func__, rc);
> > 	rc = 0;
> > }
> > 
> > Should be fairly safe play now.
> 
> Unfortuantely it isn't. You seemed to have lost the
> EXPORT_SYMBOL_GPL(tpm_chip_start/stop) and the tpm_chip_start/stop around
> the tpm2_shutdown()...

OK, now those fixes are back. In tpm_pm_shutdown() case you need also
take the lock.

/Jarkko
Stefan Berger Feb. 8, 2019, 8:32 p.m. UTC | #6
On 2/8/19 3:23 PM, Jarkko Sakkinen wrote:
> On Fri, Feb 08, 2019 at 02:27:31PM -0500, Stefan Berger wrote:
>> On 2/8/19 2:17 PM, Jarkko Sakkinen wrote:
>>>    */
>>> if (rc > 0) {
>>> 	dev_warn(&chip->dev,
>>> 		 "%s: send(): invalid value %d\n", __func__, rc);
>>> 	rc = 0;
>>> }
>>>
>>> Should be fairly safe play now.
>> Unfortuantely it isn't. You seemed to have lost the
>> EXPORT_SYMBOL_GPL(tpm_chip_start/stop) and the tpm_chip_start/stop around
>> the tpm2_shutdown()...
> OK, now those fixes are back. In tpm_pm_shutdown() case you need also
> take the lock.

tpm_del_char_device also needs the start/stop!


     Stefan


>
> /Jarkko
>
Jarkko Sakkinen Feb. 8, 2019, 8:38 p.m. UTC | #7
On Fri, Feb 08, 2019 at 10:23:53PM +0200, Jarkko Sakkinen wrote:
> On Fri, Feb 08, 2019 at 02:27:31PM -0500, Stefan Berger wrote:
> > On 2/8/19 2:17 PM, Jarkko Sakkinen wrote:
> > > 
> > >   */
> > > if (rc > 0) {
> > > 	dev_warn(&chip->dev,
> > > 		 "%s: send(): invalid value %d\n", __func__, rc);
> > > 	rc = 0;
> > > }
> > > 
> > > Should be fairly safe play now.
> > 
> > Unfortuantely it isn't. You seemed to have lost the
> > EXPORT_SYMBOL_GPL(tpm_chip_start/stop) and the tpm_chip_start/stop around
> > the tpm2_shutdown()...
> 
> OK, now those fixes are back. In tpm_pm_shutdown() case you need also
> take the lock.

I back tracked now what went wrong. When I first did these fixes I did
git reset --hard next on master after doing them and not the other way
around I supposed to. Apologies for the inconvenience...

/Jarkko
Jarkko Sakkinen Feb. 8, 2019, 8:46 p.m. UTC | #8
On Fri, Feb 08, 2019 at 03:32:32PM -0500, Stefan Berger wrote:
> On 2/8/19 3:23 PM, Jarkko Sakkinen wrote:
> > On Fri, Feb 08, 2019 at 02:27:31PM -0500, Stefan Berger wrote:
> > > On 2/8/19 2:17 PM, Jarkko Sakkinen wrote:
> > > >    */
> > > > if (rc > 0) {
> > > > 	dev_warn(&chip->dev,
> > > > 		 "%s: send(): invalid value %d\n", __func__, rc);
> > > > 	rc = 0;
> > > > }
> > > > 
> > > > Should be fairly safe play now.
> > > Unfortuantely it isn't. You seemed to have lost the
> > > EXPORT_SYMBOL_GPL(tpm_chip_start/stop) and the tpm_chip_start/stop around
> > > the tpm2_shutdown()...
> > OK, now those fixes are back. In tpm_pm_shutdown() case you need also
> > take the lock.
> 
> tpm_del_char_device also needs the start/stop!

Done and updated the commit message to have all the call sites:

    * tpm_chip_register()
    * tpm_class_shutdown()
    * tpm_del_char_device()
    * tpm_pm_suspend()
    * tpm_try_get_ops() and tpm_put_ops()
    * tpm2_del_space()

/Jarkko
Stefan Berger Feb. 8, 2019, 9:18 p.m. UTC | #9
On 2/8/19 3:46 PM, Jarkko Sakkinen wrote:
> On Fri, Feb 08, 2019 at 03:32:32PM -0500, Stefan Berger wrote:
>>
>> tpm_del_char_device also needs the start/stop!
> Done and updated the commit message to have all the call sites:
>
>      * tpm_chip_register()
>      * tpm_class_shutdown()
>      * tpm_del_char_device()
>      * tpm_pm_suspend()
>      * tpm_try_get_ops() and tpm_put_ops()
>      * tpm2_del_space()


I tested this now with tpm_vtpm_proxy, TPM 1.2, (TIS|CRB) + TPM 2.0. 
Looks good now - rock solid so to say. And while we are at it ... :-)
Jarkko Sakkinen Feb. 8, 2019, 9:51 p.m. UTC | #10
On Fri, Feb 08, 2019 at 04:18:40PM -0500, Stefan Berger wrote:
> On 2/8/19 3:46 PM, Jarkko Sakkinen wrote:
> > On Fri, Feb 08, 2019 at 03:32:32PM -0500, Stefan Berger wrote:
> > > 
> > > tpm_del_char_device also needs the start/stop!
> > Done and updated the commit message to have all the call sites:
> > 
> >      * tpm_chip_register()
> >      * tpm_class_shutdown()
> >      * tpm_del_char_device()
> >      * tpm_pm_suspend()
> >      * tpm_try_get_ops() and tpm_put_ops()
> >      * tpm2_del_space()
> 
> 
> I tested this now with tpm_vtpm_proxy, TPM 1.2, (TIS|CRB) + TPM 2.0. Looks
> good now - rock solid so to say. And while we are at it ... :-)

Thank you for your support. I don't think these quite distruptive
changes would have made in without any growing pains. The way
tpm_transmit() used to be had become quite a mess with all the nested
calls and weird locking flags. Now we have a good baseline to forward
:-)

I rebased the branches to the latest security/next-general. Probably
do the PR after the middle week (ETA Thu).

/Jarkko
Jerry Snitselaar Feb. 9, 2019, 6:20 p.m. UTC | #11
On Fri Feb 08 19, Jarkko Sakkinen wrote:
>The send() callback should never return length as it does not in every
>driver except tpm_crb in the success case. The reason is that the main
>transmit functionality only cares about whether the transmit was
>successful or not and ignores the count completely.
>
>Cc: stable@vger.kernel.org
>Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>---
> drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
> drivers/char/tpm/tpm_atmel.c         | 2 +-
> drivers/char/tpm/tpm_i2c_atmel.c     | 6 +++++-
> drivers/char/tpm/tpm_i2c_infineon.c  | 2 +-
> drivers/char/tpm/tpm_i2c_nuvoton.c   | 2 +-
> drivers/char/tpm/tpm_ibmvtpm.c       | 8 ++++----
> drivers/char/tpm/tpm_infineon.c      | 2 +-
> drivers/char/tpm/tpm_nsc.c           | 2 +-
> drivers/char/tpm/tpm_tis_core.c      | 2 +-
> drivers/char/tpm/tpm_vtpm_proxy.c    | 3 +--
> drivers/char/tpm/xen-tpmfront.c      | 2 +-
> 11 files changed, 18 insertions(+), 15 deletions(-)
>
>diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
>index 64dc560859f2..13dc614b7ebc 100644
>--- a/drivers/char/tpm/st33zp24/st33zp24.c
>+++ b/drivers/char/tpm/st33zp24/st33zp24.c
>@@ -436,7 +436,7 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
> 			goto out_err;
> 	}
>
>-	return len;
>+	return 0;
> out_err:
> 	st33zp24_cancel(chip);
> 	release_locality(chip);
>diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
>index 66a14526aaf4..a290b30a0c35 100644
>--- a/drivers/char/tpm/tpm_atmel.c
>+++ b/drivers/char/tpm/tpm_atmel.c
>@@ -105,7 +105,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
> 		iowrite8(buf[i], priv->iobase);
> 	}
>
>-	return count;
>+	return 0;
> }
>
> static void tpm_atml_cancel(struct tpm_chip *chip)
>diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
>index 4720b2442ffe..aa11c8a1df5e 100644
>--- a/drivers/char/tpm/tpm_i2c_atmel.c
>+++ b/drivers/char/tpm/tpm_i2c_atmel.c
>@@ -65,7 +65,11 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
> 	dev_dbg(&chip->dev,
> 		"%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
> 		(int)min_t(size_t, 64, len), buf, len, status);
>-	return status;
>+
>+	if (status < 0)
>+		return status;
>+
>+	return 0;
> }
>
> static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
>index 3b490d9d90e7..3b4e9672ff6c 100644
>--- a/drivers/char/tpm/tpm_i2c_infineon.c
>+++ b/drivers/char/tpm/tpm_i2c_infineon.c
>@@ -588,7 +588,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
> 	/* go and do it */
> 	iic_tpm_write(TPM_STS(tpm_dev.locality), &sts, 1);
>
>-	return len;
>+	return 0;
> out_err:
> 	tpm_tis_i2c_ready(chip);
> 	/* The TPM needs some time to clean up here,
>diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
>index 5700cc2ddee1..315a3b4548f7 100644
>--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
>+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
>@@ -465,7 +465,7 @@ static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
> 	}
>
> 	dev_dbg(dev, "%s() -> %zd\n", __func__, len);
>-	return len;
>+	return 0;
> }
>
> static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status)
>diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
>index 07b5a487d0c8..757ca45b39b8 100644
>--- a/drivers/char/tpm/tpm_ibmvtpm.c
>+++ b/drivers/char/tpm/tpm_ibmvtpm.c
>@@ -139,14 +139,14 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> }
>
> /**
>- * tpm_ibmvtpm_send - Send tpm request
>- *
>+ * tpm_ibmvtpm_send() - Send a TPM command
>  * @chip:	tpm chip struct
>  * @buf:	buffer contains data to send
>  * @count:	size of buffer
>  *
>  * Return:
>- *	Number of bytes sent or < 0 on error.
>+ *   0 on success,
>+ *   -errno on error
>  */
> static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> {
>@@ -192,7 +192,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> 		rc = 0;
> 		ibmvtpm->tpm_processing_cmd = false;
> 	} else
>-		rc = count;
>+		rc = 0;
>
> 	spin_unlock(&ibmvtpm->rtce_lock);
> 	return rc;
>diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
>index d8f10047fbba..97f6d4fe0aee 100644
>--- a/drivers/char/tpm/tpm_infineon.c
>+++ b/drivers/char/tpm/tpm_infineon.c
>@@ -354,7 +354,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
> 	for (i = 0; i < count; i++) {
> 		wait_and_send(chip, buf[i]);
> 	}
>-	return count;
>+	return 0;
> }
>
> static void tpm_inf_cancel(struct tpm_chip *chip)
>diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
>index 5d6cce74cd3f..9bee3c5eb4bf 100644
>--- a/drivers/char/tpm/tpm_nsc.c
>+++ b/drivers/char/tpm/tpm_nsc.c
>@@ -226,7 +226,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
> 	}
> 	outb(NSC_COMMAND_EOC, priv->base + NSC_COMMAND);
>
>-	return count;
>+	return 0;
> }
>
> static void tpm_nsc_cancel(struct tpm_chip *chip)
>diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>index 60e2038652b8..b9f64684c3fb 100644
>--- a/drivers/char/tpm/tpm_tis_core.c
>+++ b/drivers/char/tpm/tpm_tis_core.c
>@@ -481,7 +481,7 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> 			goto out_err;
> 		}
> 	}
>-	return len;
>+	return 0;
> out_err:
> 	tpm_tis_ready(chip);
> 	return rc;
>diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
>index 26a2be555288..d74f3de74ae6 100644
>--- a/drivers/char/tpm/tpm_vtpm_proxy.c
>+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
>@@ -335,7 +335,6 @@ static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
> static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
> {
> 	struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
>-	int rc = 0;
>
> 	if (count > sizeof(proxy_dev->buffer)) {
> 		dev_err(&chip->dev,
>@@ -366,7 +365,7 @@ static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
>
> 	wake_up_interruptible(&proxy_dev->wq);
>
>-	return rc;
>+	return 0;
> }
>
> static void vtpm_proxy_tpm_op_cancel(struct tpm_chip *chip)
>diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
>index 1259e935fd58..4e2d00cb0d81 100644
>--- a/drivers/char/tpm/xen-tpmfront.c
>+++ b/drivers/char/tpm/xen-tpmfront.c
>@@ -173,7 +173,7 @@ static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> 		return -ETIME;
> 	}
>
>-	return count;
>+	return 0;
> }
>
> static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>-- 
>2.19.1
>

Does st33zp24_i2c_send need an update as well? It does 'return write8_reg()'.
Jerry Snitselaar Feb. 9, 2019, 8:01 p.m. UTC | #12
On Sat, Feb 9, 2019 at 11:20 AM Jerry Snitselaar <jsnitsel@redhat.com> wrote:
>
> On Fri Feb 08 19, Jarkko Sakkinen wrote:
> >The send() callback should never return length as it does not in every
> >driver except tpm_crb in the success case. The reason is that the main
> >transmit functionality only cares about whether the transmit was
> >successful or not and ignores the count completely.
> >
> >Cc: stable@vger.kernel.org
> >Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> >---
> > drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
> > drivers/char/tpm/tpm_atmel.c         | 2 +-
> > drivers/char/tpm/tpm_i2c_atmel.c     | 6 +++++-
> > drivers/char/tpm/tpm_i2c_infineon.c  | 2 +-
> > drivers/char/tpm/tpm_i2c_nuvoton.c   | 2 +-
> > drivers/char/tpm/tpm_ibmvtpm.c       | 8 ++++----
> > drivers/char/tpm/tpm_infineon.c      | 2 +-
> > drivers/char/tpm/tpm_nsc.c           | 2 +-
> > drivers/char/tpm/tpm_tis_core.c      | 2 +-
> > drivers/char/tpm/tpm_vtpm_proxy.c    | 3 +--
> > drivers/char/tpm/xen-tpmfront.c      | 2 +-
> > 11 files changed, 18 insertions(+), 15 deletions(-)
> >
> >diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
> >index 64dc560859f2..13dc614b7ebc 100644
> >--- a/drivers/char/tpm/st33zp24/st33zp24.c
> >+++ b/drivers/char/tpm/st33zp24/st33zp24.c
> >@@ -436,7 +436,7 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
> >                       goto out_err;
> >       }
> >
> >-      return len;
> >+      return 0;
> > out_err:
> >       st33zp24_cancel(chip);
> >       release_locality(chip);
> >diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
> >index 66a14526aaf4..a290b30a0c35 100644
> >--- a/drivers/char/tpm/tpm_atmel.c
> >+++ b/drivers/char/tpm/tpm_atmel.c
> >@@ -105,7 +105,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
> >               iowrite8(buf[i], priv->iobase);
> >       }
> >
> >-      return count;
> >+      return 0;
> > }
> >
> > static void tpm_atml_cancel(struct tpm_chip *chip)
> >diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
> >index 4720b2442ffe..aa11c8a1df5e 100644
> >--- a/drivers/char/tpm/tpm_i2c_atmel.c
> >+++ b/drivers/char/tpm/tpm_i2c_atmel.c
> >@@ -65,7 +65,11 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
> >       dev_dbg(&chip->dev,
> >               "%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
> >               (int)min_t(size_t, 64, len), buf, len, status);
> >-      return status;
> >+
> >+      if (status < 0)
> >+              return status;
> >+
> >+      return 0;
> > }
> >
> > static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> >diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
> >index 3b490d9d90e7..3b4e9672ff6c 100644
> >--- a/drivers/char/tpm/tpm_i2c_infineon.c
> >+++ b/drivers/char/tpm/tpm_i2c_infineon.c
> >@@ -588,7 +588,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
> >       /* go and do it */
> >       iic_tpm_write(TPM_STS(tpm_dev.locality), &sts, 1);
> >
> >-      return len;
> >+      return 0;
> > out_err:
> >       tpm_tis_i2c_ready(chip);
> >       /* The TPM needs some time to clean up here,
> >diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
> >index 5700cc2ddee1..315a3b4548f7 100644
> >--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
> >+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
> >@@ -465,7 +465,7 @@ static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
> >       }
> >
> >       dev_dbg(dev, "%s() -> %zd\n", __func__, len);
> >-      return len;
> >+      return 0;
> > }
> >
> > static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status)
> >diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
> >index 07b5a487d0c8..757ca45b39b8 100644
> >--- a/drivers/char/tpm/tpm_ibmvtpm.c
> >+++ b/drivers/char/tpm/tpm_ibmvtpm.c
> >@@ -139,14 +139,14 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> > }
> >
> > /**
> >- * tpm_ibmvtpm_send - Send tpm request
> >- *
> >+ * tpm_ibmvtpm_send() - Send a TPM command
> >  * @chip:     tpm chip struct
> >  * @buf:      buffer contains data to send
> >  * @count:    size of buffer
> >  *
> >  * Return:
> >- *    Number of bytes sent or < 0 on error.
> >+ *   0 on success,
> >+ *   -errno on error
> >  */
> > static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> > {
> >@@ -192,7 +192,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> >               rc = 0;
> >               ibmvtpm->tpm_processing_cmd = false;
> >       } else
> >-              rc = count;
> >+              rc = 0;
> >
> >       spin_unlock(&ibmvtpm->rtce_lock);
> >       return rc;
> >diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
> >index d8f10047fbba..97f6d4fe0aee 100644
> >--- a/drivers/char/tpm/tpm_infineon.c
> >+++ b/drivers/char/tpm/tpm_infineon.c
> >@@ -354,7 +354,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
> >       for (i = 0; i < count; i++) {
> >               wait_and_send(chip, buf[i]);
> >       }
> >-      return count;
> >+      return 0;
> > }
> >
> > static void tpm_inf_cancel(struct tpm_chip *chip)
> >diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
> >index 5d6cce74cd3f..9bee3c5eb4bf 100644
> >--- a/drivers/char/tpm/tpm_nsc.c
> >+++ b/drivers/char/tpm/tpm_nsc.c
> >@@ -226,7 +226,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
> >       }
> >       outb(NSC_COMMAND_EOC, priv->base + NSC_COMMAND);
> >
> >-      return count;
> >+      return 0;
> > }
> >
> > static void tpm_nsc_cancel(struct tpm_chip *chip)
> >diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> >index 60e2038652b8..b9f64684c3fb 100644
> >--- a/drivers/char/tpm/tpm_tis_core.c
> >+++ b/drivers/char/tpm/tpm_tis_core.c
> >@@ -481,7 +481,7 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> >                       goto out_err;
> >               }
> >       }
> >-      return len;
> >+      return 0;
> > out_err:
> >       tpm_tis_ready(chip);
> >       return rc;
> >diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
> >index 26a2be555288..d74f3de74ae6 100644
> >--- a/drivers/char/tpm/tpm_vtpm_proxy.c
> >+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
> >@@ -335,7 +335,6 @@ static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
> > static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
> > {
> >       struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
> >-      int rc = 0;
> >
> >       if (count > sizeof(proxy_dev->buffer)) {
> >               dev_err(&chip->dev,
> >@@ -366,7 +365,7 @@ static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
> >
> >       wake_up_interruptible(&proxy_dev->wq);
> >
> >-      return rc;
> >+      return 0;
> > }
> >
> > static void vtpm_proxy_tpm_op_cancel(struct tpm_chip *chip)
> >diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
> >index 1259e935fd58..4e2d00cb0d81 100644
> >--- a/drivers/char/tpm/xen-tpmfront.c
> >+++ b/drivers/char/tpm/xen-tpmfront.c
> >@@ -173,7 +173,7 @@ static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
> >               return -ETIME;
> >       }
> >
> >-      return count;
> >+      return 0;
> > }
> >
> > static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> >--
> >2.19.1
> >
>
> Does st33zp24_i2c_send need an update as well? It does 'return write8_reg()'.

Disregard this question. It is st33zp24_send that would be the one to
change, and you already dealt with that.
Jarkko Sakkinen Feb. 11, 2019, 1:58 p.m. UTC | #13
On Sat, Feb 09, 2019 at 11:20:22AM -0700, Jerry Snitselaar wrote:
> Does st33zp24_i2c_send need an update as well? It does 'return
> write8_reg()'.

After these commits the only situation when st33zp24_i2c_send() return
value is returned back to the user space, when called from
st33zp24_send(), is when it returns -errno.

/Jarkko
Alexander Steffen Feb. 11, 2019, 3:05 p.m. UTC | #14
On 08.02.2019 20:00, Jarkko Sakkinen wrote:
> On Fri, Feb 08, 2019 at 01:12:34PM -0500, Stefan Berger wrote:
>> On 2/8/19 1:08 PM, Jarkko Sakkinen wrote:
>>> The send() callback should never return length as it does not in every
>>> driver except tpm_crb in the success case. The reason is that the main
>>> transmit functionality only cares about whether the transmit was
>>> successful or not and ignores the count completely.
>>>
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>>
>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>
>> Let me know when you put it into your tree, I'll give it a spin while I am
>> at it. :-)
> 
> Thank you Stefan! I also add your suggested-by to the first commit
> because you pointed out the problem.
> 
> It all looks now legit, but just in case I'll add a check for the return
> value to tpm_try_transmit() and a warning if it is not zero in the
> success case (and after that zeroing of rc).
> 
> That check can be removed when I do v5.3 pull request. That should
> enough window to catch any potential issues and check will ensure that
> kernel won't fail even there was something forgotten.
> 
> Alexander, I'll push this version now to the master and next with the
> additional check described in this commit, but will add your tags
> after you have time to test.

I ran all tests again and everything works now as expected :)

Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>

Alexander
Jarkko Sakkinen Feb. 13, 2019, 7:44 a.m. UTC | #15
On Mon, Feb 11, 2019 at 04:05:39PM +0100, Alexander Steffen wrote:
> Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>

Thank you!

/Jarkko

Patch
diff mbox series

diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index 64dc560859f2..13dc614b7ebc 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -436,7 +436,7 @@  static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
 			goto out_err;
 	}
 
-	return len;
+	return 0;
 out_err:
 	st33zp24_cancel(chip);
 	release_locality(chip);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 66a14526aaf4..a290b30a0c35 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -105,7 +105,7 @@  static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
 		iowrite8(buf[i], priv->iobase);
 	}
 
-	return count;
+	return 0;
 }
 
 static void tpm_atml_cancel(struct tpm_chip *chip)
diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
index 4720b2442ffe..aa11c8a1df5e 100644
--- a/drivers/char/tpm/tpm_i2c_atmel.c
+++ b/drivers/char/tpm/tpm_i2c_atmel.c
@@ -65,7 +65,11 @@  static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	dev_dbg(&chip->dev,
 		"%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
 		(int)min_t(size_t, 64, len), buf, len, status);
-	return status;
+
+	if (status < 0)
+		return status;
+
+	return 0;
 }
 
 static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 3b490d9d90e7..3b4e9672ff6c 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -588,7 +588,7 @@  static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	/* go and do it */
 	iic_tpm_write(TPM_STS(tpm_dev.locality), &sts, 1);
 
-	return len;
+	return 0;
 out_err:
 	tpm_tis_i2c_ready(chip);
 	/* The TPM needs some time to clean up here,
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
index 5700cc2ddee1..315a3b4548f7 100644
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -465,7 +465,7 @@  static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	}
 
 	dev_dbg(dev, "%s() -> %zd\n", __func__, len);
-	return len;
+	return 0;
 }
 
 static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status)
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 07b5a487d0c8..757ca45b39b8 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -139,14 +139,14 @@  static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 }
 
 /**
- * tpm_ibmvtpm_send - Send tpm request
- *
+ * tpm_ibmvtpm_send() - Send a TPM command
  * @chip:	tpm chip struct
  * @buf:	buffer contains data to send
  * @count:	size of buffer
  *
  * Return:
- *	Number of bytes sent or < 0 on error.
+ *   0 on success,
+ *   -errno on error
  */
 static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
@@ -192,7 +192,7 @@  static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 		rc = 0;
 		ibmvtpm->tpm_processing_cmd = false;
 	} else
-		rc = count;
+		rc = 0;
 
 	spin_unlock(&ibmvtpm->rtce_lock);
 	return rc;
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index d8f10047fbba..97f6d4fe0aee 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -354,7 +354,7 @@  static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
 	for (i = 0; i < count; i++) {
 		wait_and_send(chip, buf[i]);
 	}
-	return count;
+	return 0;
 }
 
 static void tpm_inf_cancel(struct tpm_chip *chip)
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 5d6cce74cd3f..9bee3c5eb4bf 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -226,7 +226,7 @@  static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
 	}
 	outb(NSC_COMMAND_EOC, priv->base + NSC_COMMAND);
 
-	return count;
+	return 0;
 }
 
 static void tpm_nsc_cancel(struct tpm_chip *chip)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 60e2038652b8..b9f64684c3fb 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -481,7 +481,7 @@  static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
 			goto out_err;
 		}
 	}
-	return len;
+	return 0;
 out_err:
 	tpm_tis_ready(chip);
 	return rc;
diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
index 26a2be555288..d74f3de74ae6 100644
--- a/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -335,7 +335,6 @@  static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
 static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
-	int rc = 0;
 
 	if (count > sizeof(proxy_dev->buffer)) {
 		dev_err(&chip->dev,
@@ -366,7 +365,7 @@  static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
 
 	wake_up_interruptible(&proxy_dev->wq);
 
-	return rc;
+	return 0;
 }
 
 static void vtpm_proxy_tpm_op_cancel(struct tpm_chip *chip)
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
index 1259e935fd58..4e2d00cb0d81 100644
--- a/drivers/char/tpm/xen-tpmfront.c
+++ b/drivers/char/tpm/xen-tpmfront.c
@@ -173,7 +173,7 @@  static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 		return -ETIME;
 	}
 
-	return count;
+	return 0;
 }
 
 static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)