Commit 71106292 authored by Tadeusz Struk's avatar Tadeusz Struk Committed by James Morris

tpm: fix an invalid condition in tpm_common_poll

The poll condition should only check response_length,
because reads should only be issued if there is data to read.
The response_read flag only prevents double writes.
The problem was that the write set the response_read to false,
enqued a tpm job, and returned. Then application called poll
which checked the response_read flag and returned EPOLLIN.
Then the application called read, but got nothing.
After all that the async_work kicked in.
Added also mutex_lock around the poll check to prevent
other possible race conditions.

Fixes: 9488585b ("tpm: add support for partial reads")
Reported-by: default avatarMantas Mikulėnas <grawity@gmail.com>
Tested-by: default avatarMantas Mikulėnas <grawity@gmail.com>
Signed-off-by: default avatarTadeusz Struk <tadeusz.struk@intel.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: default avatarJames Morris <james.morris@microsoft.com>
parent e891db1a
......@@ -233,12 +233,19 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait)
__poll_t mask = 0;
poll_wait(file, &priv->async_wait, wait);
mutex_lock(&priv->buffer_mutex);
if (!priv->response_read || priv->response_length)
/*
* The response_length indicates if there is still response
* (or part of it) to be consumed. Partial reads decrease it
* by the number of bytes read, and write resets it the zero.
*/
if (priv->response_length)
mask = EPOLLIN | EPOLLRDNORM;
else
mask = EPOLLOUT | EPOLLWRNORM;
mutex_unlock(&priv->buffer_mutex);
return mask;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment