summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-12-08 23:11:27 -0800
committerGerrit <chrome-bot@google.com>2012-12-10 13:56:47 -0800
commit34d515c5c19fb2ca79d212eb7fa837a455a20321 (patch)
tree3e6a7f209e7e3502341ad65fb3c9d1fd1a4bd76f
parent00cc72894f3ce5c3b0d337e424f19da089140237 (diff)
downloadvboot-34d515c5c19fb2ca79d212eb7fa837a455a20321.tar.gz
mount-encrypted: retry TPM open
If the TPM hits an error other than ENOENT during open(), retry for 5 seconds with 100ms polling delays. Also switch to on-demand opening of TPM, so umount will not hit delays if tcsd keeps the TPM open at shutdown time. BUG=chrome-os-partner:15960 TEST=daisy build, mount ok with kernel patched to return EBUSY for a few opens, platform_EncryptedStateful passes. BRANCH=None Change-Id: Ia597622bb54ccc4366be2a0c960c518406e6c0b2 Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/39445 Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
-rw-r--r--utility/mount-encrypted.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/utility/mount-encrypted.c b/utility/mount-encrypted.c
index 2c975a39..39777e9d 100644
--- a/utility/mount-encrypted.c
+++ b/utility/mount-encrypted.c
@@ -110,14 +110,40 @@ static gchar *encrypted_mount = NULL;
static gchar *dmcrypt_name = NULL;
static gchar *dmcrypt_dev = NULL;
static int has_tpm = 0;
+static int tpm_init_called = 0;
static void tpm_init(void)
{
uint32_t result;
+ struct timespec delay;
+ int retries;
+
+ if (tpm_init_called)
+ return;
DEBUG("Opening TPM");
setenv("TPM_NO_EXIT", "1", 1);
- result = TlclLibInit();
+
+ /* Retry TPM opening for 5 seconds (500 10ms sleeps). */
+ for (retries = 0; retries < 500; ++ retries) {
+ errno = 0;
+ result = TlclLibInit();
+ if (result == TPM_SUCCESS)
+ break;
+
+ INFO("Could not open TPM: error 0x%02x (%s).", result,
+ strerror(errno));
+ /* Assume ENOENT will never recover */
+ if (errno == ENOENT)
+ break;
+
+ /* Stall 10ms until TPM comes back. */
+ delay.tv_sec = 0;
+ delay.tv_nsec = 10000000;
+ nanosleep(&delay, NULL);
+ }
+
+ tpm_init_called = 1;
has_tpm = (result == TPM_SUCCESS);
INFO("TPM %s", has_tpm ? "ready" : "not available");
}
@@ -129,6 +155,7 @@ static uint32_t tpm_owned(uint8_t *owned)
{
uint32_t result;
+ tpm_init();
DEBUG("Reading TPM Ownership Flag");
if (!has_tpm)
result = TPM_E_NO_DEVICE;
@@ -141,7 +168,10 @@ static uint32_t tpm_owned(uint8_t *owned)
static void tpm_close(void)
{
+ if (!has_tpm || !tpm_init_called)
+ return;
TlclLibClose();
+ tpm_init_called = 0;
}
static void sha256(char *string, uint8_t *digest)
@@ -237,6 +267,7 @@ _read_nvram(uint8_t *buffer, size_t len, uint32_t index, uint32_t size)
return 0;
}
+ tpm_init();
DEBUG("Reading NVRAM area 0x%x (size %u)", index, size);
if (!has_tpm)
result = TPM_E_NO_DEVICE;
@@ -425,6 +456,7 @@ static int get_random_bytes_tpm(unsigned char *buffer, int wanted)
{
uint32_t remaining = wanted;
+ tpm_init();
/* Read random bytes from TPM, which can return short reads. */
while (remaining) {
uint32_t result, size;
@@ -1258,7 +1290,6 @@ int main(int argc, char *argv[])
INFO_INIT("Starting.");
prepare_paths();
- tpm_init();
if (argc > 1) {
if (!strcmp(argv[1], "umount"))