Merge remote-tracking branch 'goog/upstream-master' into merge-citadel-mutex
* goog/upstream-master:
Datagram: add mutex to protect data buffers
Bug: 111653201
Test: try and race transactions, they no longer fail
Change-Id: Ibec950c3e27c3cd91e25bb8dbe6324562d588e50
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 @@
#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 @@
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 @@
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) {