summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-07-16 15:59:44 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-07-25 00:14:49 -0700
commita820cb1255c995f0d95a15de0134f6b0cf895c64 (patch)
tree243ed715efc338dfd7774f460f226491e0bdaef0 /common
parent30b2d3917316970182c8ada8ac6d95f8ae631838 (diff)
downloadchrome-ec-a820cb1255c995f0d95a15de0134f6b0cf895c64.tar.gz
common/flash: Abort rwsig when RW is erased/written to
If RW region is being erased/written to, make sure RO does not automatically jump to RW after the timeout: RO would normally verify RW, then wait for 1 second before jumping to RW, to allow host to issue host commands in the mean time. The problem is that some of these host commands may modify the RW, which would essentially bypass the signature check. This was not important on hammer, as STM32F0 does not support EC_FLASH_PROTECT_ALL_NOW, and would force another reboot after an update to lock the flash again, and verification would run again. Other STM32 variants are able to immediately lock the flash, so no reboot is required, and there is therefore a risk that the EC would jump to an RW image that is not signed. BRANCH=none BUG=b:111190988 TEST=./ectool --name=cros_fp reboot_ec Then, quickly (while EC still in RO) ./ectool --name=cros_fp flasherase 0x120000 131072 Succeeds, and EC does not jump to RW. TEST=Increment rollback number in RW (CONFIG_ROLLBACK_VERSION), see that update works, and rollbackinfo shows updated version. Change-Id: Iaf8e1802cf5c67cafbfda575d7202e00068c6f9b Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1139952 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/flash.c15
-rw-r--r--common/rwsig.c7
2 files changed, 20 insertions, 2 deletions
diff --git a/common/flash.c b/common/flash.c
index 6e7d8dba6b..f98bf95a1e 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -12,6 +12,7 @@
#include "hooks.h"
#include "host_command.h"
#include "otp.h"
+#include "rwsig.h"
#include "shared_mem.h"
#include "system.h"
#include "util.h"
@@ -505,6 +506,20 @@ static void flash_abort_or_invalidate_hash(int offset, int size)
/* If EC executes in place, we need to invalidate the cached hash. */
vboot_hash_invalidate(offset, size);
#endif
+
+#ifdef HAS_TASK_RWSIG
+ /*
+ * If RW flash has been written to, make sure we do not automatically
+ * jump to RW after the timeout.
+ */
+ if ((offset >= CONFIG_RW_MEM_OFF &&
+ offset < (CONFIG_RW_MEM_OFF + CONFIG_RW_SIZE)) ||
+ ((offset + size) > CONFIG_RW_MEM_OFF &&
+ (offset + size) <= (CONFIG_RW_MEM_OFF + CONFIG_RW_SIZE)) ||
+ (offset < CONFIG_RW_MEM_OFF &&
+ (offset + size) > (CONFIG_RW_MEM_OFF + CONFIG_RW_SIZE)))
+ rwsig_abort();
+#endif
}
int flash_write(int offset, int size, const char *data)
diff --git a/common/rwsig.c b/common/rwsig.c
index 6c3def7afc..0e19f06914 100644
--- a/common/rwsig.c
+++ b/common/rwsig.c
@@ -198,8 +198,11 @@ int rwsig_check_signature(void)
* Signature verified: we know that rw_rollback_version is valid, check
* if rollback information should be updated.
*
- * When system is locked, we only increment the rollback if RW is
- * currently protected (and if CONFIG_FLASH_PROTECT_RW is defined).
+ * If the RW region can be protected independently
+ * (CONFIG_FLASH_PROTECT_RW is defined), and system is locked, we only
+ * increment the rollback if RW is currently protected.
+ *
+ * Otherwise, we immediately increment the rollback version.
*/
if (rw_rollback_version != min_rollback_version
#ifdef CONFIG_FLASH_PROTECT_RW