diff options
author | Brian J. Nemec <bnemec@chromium.org> | 2020-02-18 13:47:10 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-27 23:53:24 +0000 |
commit | 4236880b936d76d0b6026ba190e4b5b3f74014a1 (patch) | |
tree | 9002dda5f58dbfea25d1b327c167bcaeeefd25c3 /common/flash.c | |
parent | a7c823e0116f2b310763ce0a10bb9c938ff90d1a (diff) | |
download | chrome-ec-4236880b936d76d0b6026ba190e4b5b3f74014a1.tar.gz |
common/flash: Adds validation to setting serial
Adds a simple validation to the serial number to verify it fits
within the buffer allocated to it. If a serial number is passed
that is too long, it will no longer be silently truncated, instead
an invalid argument will show up on the console. Also performed a
small bit of cleanup on the function to eliminate extra loops
and replace them with memset and memcpy functions.
BUG=b:149775650
TEST=Verified that we can set and load serial numbers correctly.
On ServoV4 where CONFIG_SERIALNO_LEN = 28:
Verified that serial numbers up to 27 characters can be set and loaded.
Verified 28 characters and longer return error codes.
Change-Id: I9b4fb269a59023001a0fa8c1e8fc810db320fb8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2063368
Tested-by: Brian Nemec <bnemec@chromium.org>
Reviewed-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org>
Commit-Queue: Brian Nemec <bnemec@chromium.org>
Diffstat (limited to 'common/flash.c')
-rw-r--r-- | common/flash.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/common/flash.c b/common/flash.c index f2b871ee0f..3d2802f118 100644 --- a/common/flash.c +++ b/common/flash.c @@ -386,7 +386,7 @@ const char *flash_read_pstate_serial(void) */ int flash_write_pstate_serial(const char *serialno) { - int i; + int length; struct persist_state newpstate; const struct persist_state *pstate = (const struct persist_state *) @@ -396,18 +396,22 @@ int flash_write_pstate_serial(const char *serialno) if (!serialno) return EC_ERROR_INVAL; + length = strnlen(serialno, sizeof(newpstate.serialno)); + if (length >= sizeof(newpstate.serialno)) { + return EC_ERROR_INVAL; + } + /* Cache the old copy for read/modify/write. */ memcpy(&newpstate, pstate, sizeof(newpstate)); validate_pstate_struct(&newpstate); - /* Copy in serialno. */ - for (i = 0; i < CONFIG_SERIALNO_LEN - 1; i++) { - newpstate.serialno[i] = serialno[i]; - if (serialno[i] == 0) - break; - } - for (; i < CONFIG_SERIALNO_LEN; i++) - newpstate.serialno[i] = 0; + /* + * Erase any prior data and copy the string. The length was verified to + * be shorter than the buffer so a null terminator always remains. + */ + memset(newpstate.serialno, '\0', sizeof(newpstate.serialno)); + memcpy(newpstate.serialno, serialno, length); + newpstate.valid_fields |= PSTATE_VALID_SERIALNO; return flash_write_pstate_data(&newpstate); |