diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-12-10 15:23:57 -0800 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-12-10 15:42:21 -0800 |
commit | ab727c4941ddd0112be0e0de61c2900ae60913e7 (patch) | |
tree | 43cf3a0e39d3a771900423710c11f1d11a340b26 | |
parent | 7a2e3372eef4d8eee8ee140f517a309dc7065887 (diff) | |
download | chrome-ec-ab727c4941ddd0112be0e0de61c2900ae60913e7.tar.gz |
Add more paranoia for flash write protect
If the entire flash is protected (as it normally is after software
sync), fail all flash write/erase operations.
Add a shadow copy of the all_now flag.
BUG=chrome-os-partner:16727
BRANCH=link
TEST=manual
Verify that flash operations work properly before all_now. Then enable HW WP
and
flashwp enable
flashwp now
and try
flasherase 0x38000 0x1000
flashwrite 0x38000 0x100
Those commands should fail with error 7
From the host side
ectool flasherase 0x38000 0x1000
echo 'Khaaaaaaaaaaan' > /tmp/b16727
ectool flashwrite 0x38000 /tmp/b16727
should also fail.
Change-Id: I99a4d2bb86080bd12c900582a8fbdfc79c99916c
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/39517
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | chip/lm4/flash.c | 20 | ||||
-rw-r--r-- | common/flash_common.c | 12 |
2 files changed, 32 insertions, 0 deletions
diff --git a/chip/lm4/flash.c b/chip/lm4/flash.c index 51d9a46577..121936c26b 100644 --- a/chip/lm4/flash.c +++ b/chip/lm4/flash.c @@ -38,6 +38,7 @@ #define RO_BANK_COUNT (CONFIG_SECTION_RO_SIZE / CONFIG_FLASH_BANK_SIZE) int stuck_locked; /* Is physical flash stuck protected? */ +int all_protected; /* Has all-flash protection been requested? */ /* Persistent protection state - emulates a SPI status register for flashrom */ struct persist_state { @@ -162,6 +163,9 @@ static int write_buffer(void) { int t; + if (all_protected) + return EC_ERROR_ACCESS_DENIED; + if (!LM4_FLASH_FWBVAL) return EC_SUCCESS; /* Nothing to do */ @@ -201,6 +205,9 @@ int flash_physical_write(int offset, int size, const char *data) int rv; int i; + if (all_protected) + return EC_ERROR_ACCESS_DENIED; + /* Get initial write buffer index and page */ LM4_FLASH_FMA = offset & ~(FLASH_FWB_BYTES - 1); i = (offset >> 2) & (FLASH_FWB_WORDS - 1); @@ -228,6 +235,9 @@ int flash_physical_write(int offset, int size, const char *data) int flash_physical_erase(int offset, int size) { + if (all_protected) + return EC_ERROR_ACCESS_DENIED; + LM4_FLASH_FCMISC = LM4_FLASH_FCRIS; /* Clear previous error status */ for ( ; size > 0; size -= CONFIG_FLASH_ERASE_SIZE, @@ -280,6 +290,10 @@ uint32_t flash_get_protect(void) uint32_t flags = 0; int i; + /* Read all-protected state from our shadow copy */ + if (all_protected) + flags |= EC_FLASH_PROTECT_ALL_NOW; + /* Read the current persist state from flash */ read_pstate(&pstate); if (pstate.flags & PERSIST_FLAG_PROTECT_RO) @@ -355,6 +369,7 @@ int flash_set_protect(uint32_t mask, uint32_t flags) if ((mask & EC_FLASH_PROTECT_ALL_NOW) && (flags & EC_FLASH_PROTECT_ALL_NOW)) { /* Protect the entire flash */ + all_protected = 1; protect_banks(0, CONFIG_FLASH_PHYSICAL_SIZE / CONFIG_FLASH_BANK_SIZE); } @@ -391,6 +406,11 @@ int flash_pre_init(void) /* Re-read flags */ prot_flags = flash_get_protect(); } + + /* Update all-now flag if all flash is protected */ + if (prot_flags & EC_FLASH_PROTECT_ALL_NOW) + all_protected = 1; + } else { /* Don't want RO flash protected */ unwanted_prot_flags |= EC_FLASH_PROTECT_RO_NOW; diff --git a/common/flash_common.c b/common/flash_common.c index 11cb8150f3..9407f3336a 100644 --- a/common/flash_common.c +++ b/common/flash_common.c @@ -155,6 +155,9 @@ static int command_flash_erase(int argc, char **argv) int size = CONFIG_FLASH_ERASE_SIZE; int rv; + if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) + return EC_ERROR_ACCESS_DENIED; + rv = parse_offset_size(argc, argv, 1, &offset, &size); if (rv) return rv; @@ -175,6 +178,9 @@ static int command_flash_write(int argc, char **argv) char *data; int i; + if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) + return EC_ERROR_ACCESS_DENIED; + rv = parse_offset_size(argc, argv, 1, &offset, &size); if (rv) return rv; @@ -268,6 +274,9 @@ static int flash_command_write(struct host_cmd_handler_args *args) { const struct ec_params_flash_write *p = args->params; + if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) + return EC_RES_ACCESS_DENIED; + if (p->size > sizeof(p->data)) return EC_RES_INVALID_PARAM; @@ -287,6 +296,9 @@ static int flash_command_erase(struct host_cmd_handler_args *args) { const struct ec_params_flash_erase *p = args->params; + if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) + return EC_RES_ACCESS_DENIED; + if (system_unsafe_to_overwrite(p->offset, p->size)) return EC_RES_ACCESS_DENIED; |