summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2012-06-22 14:44:02 +0800
committerGerrit <chrome-bot@google.com>2012-06-27 00:55:05 -0700
commit66b47ba37d3658cceecf30d25edc3becbb692c4a (patch)
treeba451f20876d41160d23abeb47c17119ddbac69b
parent455b119dc0f3cd5538c4a53f0e2ab38534bcdf14 (diff)
downloadvboot-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.c66
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(&params->type_guid, tmp, sizeof(tmp));
+ strncat(buf, "-t ", sizeof(buf));
+ strncat(buf, tmp, sizeof(buf));
+ strncat(buf, " ", sizeof(buf));
+ }
+ if (params->set_unique) {
+ GuidToStr(&params->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;
}
-