diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-06-22 14:44:02 +0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-06-27 00:55:05 -0700 |
commit | 66b47ba37d3658cceecf30d25edc3becbb692c4a (patch) | |
tree | ba451f20876d41160d23abeb47c17119ddbac69b | |
parent | 455b119dc0f3cd5538c4a53f0e2ab38534bcdf14 (diff) | |
download | vboot-66b47ba37d3658cceecf30d25edc3becbb692c4a.tar.gz |
cgpt: verify the modifications of 'cgpt add' before effected.
Current code only does basic check on parameters, but doesn't validate
if it can pass the CheckEntries(). So a user can accidentally break
the cgpt table by:
cgpt add /dev/sda -i 6 -s 0 # 0 sector is not allowed for a partition.
cgpt show /dev/sda
... INVALID_ENTRIES ...
This CL checks the new entry before we write it to disk. If new entry is
not good, we return fail.
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
BUG=None
TEST=tested on link.
% cgpt add /dev/sda -i 6 -s 0
ERROR: cgpt add: A given parameter is not allowed.
% cgpt show /dev/sda
(no error, and partition 6 is still good)
Change-Id: Iee0ad24f73ca12028c0b8a0a5490b67c815488cf
Reviewed-on: https://gerrit.chromium.org/gerrit/25914
Commit-Ready: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
Reviewed-by: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
Tested-by: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
-rw-r--r-- | cgpt/cgpt_add.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index a3d0fb99..f72b4de5 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -9,6 +9,59 @@ #include "cgptlib_internal.h" #include "cgpt_params.h" + +static const char* DumpCgptAddParams(const CgptAddParams *params) { + static char buf[256]; + char tmp[64]; + + buf[0] = 0; + snprintf(tmp, sizeof(tmp), "-i %d ", params->partition); + strncat(buf, tmp, sizeof(buf)); + if (params->label) { + snprintf(tmp, sizeof(tmp), "-l %s ", params->label); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_begin) { + snprintf(tmp, sizeof(tmp), "-b %llu ", (unsigned long long)params->begin); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_size) { + snprintf(tmp, sizeof(tmp), "-s %llu ", (unsigned long long)params->size); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_type) { + GuidToStr(¶ms->type_guid, tmp, sizeof(tmp)); + strncat(buf, "-t ", sizeof(buf)); + strncat(buf, tmp, sizeof(buf)); + strncat(buf, " ", sizeof(buf)); + } + if (params->set_unique) { + GuidToStr(¶ms->unique_guid, tmp, sizeof(tmp)); + strncat(buf, "-u ", sizeof(buf)); + strncat(buf, tmp, sizeof(buf)); + strncat(buf, " ", sizeof(buf)); + } + if (params->set_successful) { + snprintf(tmp, sizeof(tmp), "-S %d ", params->successful); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_tries) { + snprintf(tmp, sizeof(tmp), "-T %d ", params->tries); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_priority) { + snprintf(tmp, sizeof(tmp), "-P %d ", params->priority); + strncat(buf, tmp, sizeof(buf)); + } + if (params->set_raw) { + snprintf(tmp, sizeof(tmp), "-A 0x%x ", params->raw_value); + strncat(buf, tmp, sizeof(buf)); + } + + strncat(buf, "\n", sizeof(buf)); + return buf; +} + // This is an internal helper function which assumes no NULL args are passed. // It sets the given attribute values for a single entry at the given index. static void set_entry_attributes(struct drive drive, @@ -177,7 +230,7 @@ int cgpt_add(CgptAddParams *params) { struct drive drive; int gpt_retval; - GptEntry *entry; + GptEntry *entry, backup; uint32_t index; if (params == NULL) @@ -221,6 +274,7 @@ int cgpt_add(CgptAddParams *params) { goto bad; } } + memcpy(&backup, entry, sizeof(backup)); // New partitions must specify type, begin, and size. if (IsZero(&entry->type)) { @@ -265,6 +319,15 @@ int cgpt_add(CgptAddParams *params) { GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); UpdateCrc(&drive.gpt); + // If the modified entry is illegal, recovery it and return error. + if (0 != CheckEntries((GptEntry*)drive.gpt.primary_entries, + (GptHeader*)drive.gpt.primary_header)) { + memcpy(entry, &backup, sizeof(*entry)); + Error("At least a parameter is not allowed:\n"); + Error(DumpCgptAddParams(params)); + goto bad; + } + // Write it all out. return DriveClose(&drive, 1); @@ -272,4 +335,3 @@ bad: DriveClose(&drive, 0); return CGPT_FAILED; } - |