tpm2: fix TIS locality timeout problems
Subsystems (2)
James Bottomley
maintainerPATCH 1/1 tpm2: fix TIS locality timeout problems
It has been reported that some TIS based TPMs are giving unexpected errors when using the O_NONBLOCK path. The problem is that some TPMs don't like it when you get and then relinquish a locality (as the tpm_try_get_ops/tpm_put_ops pair does) without sending a command. This currently happens all the time in the O_NONBLOCK write path. We can fix this by moving the tpm_try_get_ops further down the code to after the O_NONBLOCK determination is made. This is safe because the priv->buffer_mutex still protects the priv state being modified.
--- drivers/char/tpm/tpm-dev-common.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/char/tpm/tpm-dev-common.c +9 -10
@@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, goto out; } -/* atomic tpm command send and result receive. We only hold the ops -* lock during this period so that the tpm can be unregistered even if -* the char dev is held open. -*/ -if (tpm_try_get_ops (priv->chip)) { - ret = -EPIPE ; - goto out; - } - priv->response_length =0 ; priv->response_read = false; *off =0 ;
@@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,if (file->f_flags &O_NONBLOCK ) { priv->command_enqueued = true;queue_work (tpm_dev_wq, &priv->async_work); -tpm_put_ops (priv->chip);mutex_unlock (&priv->buffer_mutex);return size; } +/* atomic tpm command send and result receive. We only hold the ops +* lock during this period so that the tpm can be unregistered even if +* the char dev is held open. +*/ +if (tpm_try_get_ops (priv->chip)) { + ret = -EPIPE ; + goto out; + } + ret =tpm_dev_transmit (priv->chip, priv->space, priv->data_buffer,sizeof (priv->data_buffer));tpm_put_ops (priv->chip);
Signature · 1 line
2.26.2
Quoted 21 lines
-----Original Message-----
From: James Bottomley <[email protected]>
Sent: Tuesday, May 26, 2020 7:25 PM
To: [email protected]
Cc: Jarkko Sakkinen; Jason Gunthorpe; Limonciello, Mario; Alex Guzman
Subject: [PATCH] tpm2: fix TIS locality timeout problems[EXTERNAL EMAIL]
It has been reported that some TIS based TPMs are giving unexpected errors when using the
O_NONBLOCKpath. The problem is that some TPMs don't like it when you get and then relinquish a locality (as the tpm_try_get_ops/tpm_put_ops pair does) without sending a command. This currently happens all the time in theO_NONBLOCKwrite path. We can fix this by moving thetpm_try_get_opsfurther down the code to after theO_NONBLOCKdetermination is made. This is safe because thepriv->buffer_mutexstill protects the priv state being modified.
Quoted 4 lines
Fixes d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")Reported-by Mario Limonciello <[email protected]>Tested-by Alex Guzman <[email protected]>Signed-off-by James Bottomley <[email protected]>
A few other notes for right here:
* You should probably mention this buglink:
* And add another Reported-by: For Alex probably makes sense , as he is the original reporter to the bug. I just helped to bring it here.
* This should CC stable (as this regression managed to hit the stable kernels too).
Quoted 50 lines
--- drivers/char/tpm/tpm-dev-common.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)drivers/char/tpm/tpm-dev- renamed from drivers/char/tpm/tpm-dev-common.c +0
-0
common.c
index87f449340202..1784530b8387100644drivers/char/tpm/tpm-dev-common.c +0
-9@@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char__user *buf, goto out; } -/* atomic tpm command send and result receive. We only hold the ops -* lock during this period so that the tpm can be unregistered even if -* the char dev is held open. -*/ -if (tpm_try_get_ops (priv->chip)) { - ret = -EPIPE ; - goto out; - } - priv->response_length =0 ; priv->response_read = false;drivers/char/tpm/tpm-dev-common.c +9
-1*off =0 ;@@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char__user *buf, if (file->f_flags & O_NONBLOCK) { priv->command_enqueued = true;queue_work (tpm_dev_wq, &priv->async_work); -tpm_put_ops (priv->chip);mutex_unlock (&priv->buffer_mutex);return size; } +/* atomic tpm command send and result receive. We only hold the ops +* lock during this period so that the tpm can be unregistered even if +* the char dev is held open. +*/ +if (tpm_try_get_ops (priv->chip)) { + ret = -EPIPE ; + goto out; + } + ret =tpm_dev_transmit (priv->chip, priv->space, priv->data_buffer,sizeof (priv->data_buffer));
tpm_put_ops(priv->chip);
--
2.26.2
Quoted 9 lines · James Bottomley
It has been reported that some TIS based TPMs are giving unexpected errors when using the
O_NONBLOCKpath. The problem is that some TPMs don't like it when you get and then relinquish a locality (as the tpm_try_get_ops/tpm_put_ops pair does) without sending a command. This currently happens all the time in theO_NONBLOCKwrite path. We can fix this by moving thetpm_try_get_opsfurther down the code to after theO_NONBLOCKdetermination is made. This is safe because thepriv->buffer_mutexstill protects the priv state being modified.
Quoted 4 lines
Fixes d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")Reported-by Mario Limonciello <[email protected]>Tested-by Alex Guzman <[email protected]>Signed-off-by James Bottomley <[email protected]>
Quoted 9 lines · James Bottomley
It has been reported that some TIS based TPMs are giving unexpected errors when using the
O_NONBLOCKpath. The problem is that some TPMs don't like it when you get and then relinquish a locality (as the tpm_try_get_ops/tpm_put_ops pair does) without sending a command. This currently happens all the time in theO_NONBLOCKwrite path. We can fix this by moving thetpm_try_get_opsfurther down the code to after theO_NONBLOCKdetermination is made. This is safe because thepriv->buffer_mutexstill protects the priv state being modified.
Quoted 4 lines
Fixes d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")Reported-by Mario Limonciello <[email protected]>Tested-by Alex Guzman <[email protected]>Signed-off-by James Bottomley <[email protected]>
Subsystem tag is wrong, function name is missing '()' after and sometimes there are spaces after ".". Please fix the commit message and I can look at the code when it is clean.
/Jarkko