aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Scull <ascull@google.com>2018-07-20 14:45:09 +0100
committerAndrew Scull <ascull@google.com>2018-07-20 14:45:09 +0100
commit73e22b076268a30f7e9c058832ff71306799b8df (patch)
tree0f6d00171647b980ac78996901b769c2b1eadeab
parent20fc103aab5a2c3fd1835b7ddc4591e18dcbb8cb (diff)
downloadandroid-73e22b076268a30f7e9c058832ff71306799b8df.tar.gz
Datagram: add mutex to protect data buffers
The driver is thread safe but the buffers are shared across threads. Adding mutexes around the use of the buffers prevents race conditions that were causing transaction failures. Bug: 111653201 Test: try and race transactions, they no longer fail Change-Id: If58f203eb31075174e5d15eaaea4405eb5082342
-rw-r--r--citadel/libnos_datagram/citadel.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/citadel/libnos_datagram/citadel.c b/citadel/libnos_datagram/citadel.c
index cea0a42..f2ba9ba 100644
--- a/citadel/libnos_datagram/citadel.c
+++ b/citadel/libnos_datagram/citadel.c
@@ -24,6 +24,7 @@
#include <getopt.h>
#include <linux/types.h>
#include <poll.h>
+#include <pthread.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -47,6 +48,7 @@ struct citadel_ioc_tpm_datagram {
#define DEV_CITADEL "/dev/citadel0"
+static pthread_mutex_t in_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint8_t in_buf[MAX_DEVICE_TRANSFER];
static int read_datagram(void *ctx, uint32_t command, uint8_t *buf, uint32_t len) {
struct citadel_ioc_tpm_datagram dg = {
@@ -74,17 +76,30 @@ static int read_datagram(void *ctx, uint32_t command, uint8_t *buf, uint32_t len
return -E2BIG;
}
+ /* Lock the in buffer while it is used for this transaction */
+ if (pthread_mutex_lock(&in_buf_mutex) != 0) {
+ ALOGE("%s: failed to lock in_buf_mutex: %s", __func__, strerror(errno));
+ return -errno;
+ }
+
ret = ioctl(fd, CITADEL_IOC_TPM_DATAGRAM, &dg);
if (ret < 0) {
ALOGE("can't send spi message: %s", strerror(errno));
- return -errno;
+ ret = -errno;
+ goto out;
}
memcpy(buf, in_buf, len);
- return 0;
+out:
+ if (pthread_mutex_unlock(&in_buf_mutex) != 0) {
+ ALOGE("%s: failed to unlock in_buf_mutex: %s", __func__, strerror(errno));
+ ret = -errno;
+ }
+ return ret;
}
+static pthread_mutex_t out_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint8_t out_buf[MAX_DEVICE_TRANSFER];
static int write_datagram(void *ctx, uint32_t command, const uint8_t *buf, uint32_t len) {
struct citadel_ioc_tpm_datagram dg = {
@@ -111,15 +126,27 @@ static int write_datagram(void *ctx, uint32_t command, const uint8_t *buf, uint3
return -E2BIG;
}
+ /* Lock the out buffer while it is used for this transaction */
+ if (pthread_mutex_lock(&out_buf_mutex) != 0) {
+ ALOGE("%s: failed to lock out_buf_mutex: %s", __func__, strerror(errno));
+ return -errno;
+ }
+
memcpy(out_buf, buf, len);
ret = ioctl(fd, CITADEL_IOC_TPM_DATAGRAM, &dg);
if (ret < 0) {
ALOGE("can't send spi message: %s", strerror(errno));
- return -errno;
+ ret = -errno;
+ goto out;
}
- return 0;
+out:
+ if (pthread_mutex_unlock(&out_buf_mutex) != 0) {
+ ALOGE("%s: failed to unlock out_buf_mutex: %s", __func__, strerror(errno));
+ ret = -errno;
+ }
+ return ret;
}
static int wait_for_interrupt(void *ctx, int msecs) {