[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191229172726.284691037@linuxfoundation.org>
Date: Sun, 29 Dec 2019 18:26:59 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Jeffrin Jose T <jeffrin@...agiritech.edu.in>,
Tadeusz Struk <tadeusz.struk@...el.com>,
Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
Subject: [PATCH 5.4 366/434] tpm: fix invalid locking in NONBLOCKING mode
From: Tadeusz Struk <tadeusz.struk@...el.com>
commit d23d12484307b40eea549b8a858f5fffad913897 upstream.
When an application sends TPM commands in NONBLOCKING mode
the driver holds chip->tpm_mutex returning from write(),
which triggers: "WARNING: lock held when returning to user space".
To fix this issue the driver needs to release the mutex before
returning and acquire it again in tpm_dev_async_work() before
sending the command.
Cc: stable@...r.kernel.org
Fixes: 9e1b74a63f776 (tpm: add support for nonblocking operation)
Reported-by: Jeffrin Jose T <jeffrin@...agiritech.edu.in>
Tested-by: Jeffrin Jose T <jeffrin@...agiritech.edu.in>
Signed-off-by: Tadeusz Struk <tadeusz.struk@...el.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/char/tpm/tpm-dev-common.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -61,6 +61,12 @@ static void tpm_dev_async_work(struct wo
mutex_lock(&priv->buffer_mutex);
priv->command_enqueued = false;
+ ret = tpm_try_get_ops(priv->chip);
+ if (ret) {
+ priv->response_length = ret;
+ goto out;
+ }
+
ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer));
tpm_put_ops(priv->chip);
@@ -68,6 +74,7 @@ static void tpm_dev_async_work(struct wo
priv->response_length = ret;
mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
}
+out:
mutex_unlock(&priv->buffer_mutex);
wake_up_interruptible(&priv->async_wait);
}
@@ -204,6 +211,7 @@ ssize_t tpm_common_write(struct file *fi
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;
}
Powered by blists - more mailing lists