summaryrefslogtreecommitdiff
path: root/common/flash.c
diff options
context:
space:
mode:
authorBrian J. Nemec <bnemec@chromium.org>2020-02-18 13:47:10 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-27 23:53:24 +0000
commit4236880b936d76d0b6026ba190e4b5b3f74014a1 (patch)
tree9002dda5f58dbfea25d1b327c167bcaeeefd25c3 /common/flash.c
parenta7c823e0116f2b310763ce0a10bb9c938ff90d1a (diff)
downloadchrome-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.c22
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);