diff options
author | Rob Austein <sra@hactrn.net> | 2017-04-23 18:30:50 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2017-04-23 18:30:50 -0400 |
commit | c9fc4a5779db08a6c8a0029b779826a188d8b438 (patch) | |
tree | 35a17eb13db940ce8cd67f38a683f325c150348b /ks_flash.c | |
parent | f502844d18282c928cf5fedb483514c1fcfd0b92 (diff) |
Avoid deadlock triggered by low-probability race condition.
Static code analysis (Doxygen call graph) detected a low-probability
race condition which could have triggered a deadlock on the keystore
mutex if the mkmif code returns with an error like HAL_ERROR_CORE_BUSY
when we're trying to fetch the KEK.
This is a knock-on effect of the awful kludge of backing up the KEK in
the keystore flash as an alternative to powering the MKM with a
battery as called for in the design. This code path should not exist
at all, but, for now, we avoid the deadlock by making it the caller's
responsibility to grab the keystore mutex before looking up the KEK.
Diffstat (limited to 'ks_flash.c')
-rw-r--r-- | ks_flash.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -2119,7 +2119,7 @@ hal_error_t hal_set_pin(const hal_user_t user, * while re-implementing it on top of the new keystore. */ -hal_error_t hal_mkm_flash_read(uint8_t *buf, const size_t len) +hal_error_t hal_mkm_flash_read_no_lock(uint8_t *buf, const size_t len) { if (buf != NULL && len != KEK_LENGTH) return HAL_ERROR_MASTERKEY_BAD_LENGTH; @@ -2128,18 +2128,22 @@ hal_error_t hal_mkm_flash_read(uint8_t *buf, const size_t len) hal_error_t err; unsigned b; - hal_ks_lock(); - if ((err = fetch_pin_block(&b, &block)) != HAL_OK) - goto done; + return err; if (block->pin.kek_set != FLASH_KEK_SET) - err = HAL_ERROR_MASTERKEY_NOT_SET; + return HAL_ERROR_MASTERKEY_NOT_SET; - else if (buf != NULL) + if (buf != NULL) memcpy(buf, block->pin.kek, len); - done: + return HAL_OK; +} + +hal_error_t hal_mkm_flash_read(uint8_t *buf, const size_t len) +{ + hal_ks_lock(); + const hal_error_t err = hal_mkm_flash_read_no_lock(buf, len); hal_ks_unlock(); return err; } |