diff options
author | Bill Richardson <wfrichar@chromium.org> | 2012-04-30 11:33:13 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-05-02 22:34:32 -0700 |
commit | 23429d3d782f7506fb4747356974294cce08ac47 (patch) | |
tree | 2c98d253f97d92b3c48ea3d87d4375e64f8ea4cd | |
parent | 81f704edad78f03deed5ef899a55e9d0c28dd16c (diff) | |
download | vboot-23429d3d782f7506fb4747356974294cce08ac47.tar.gz |
Let cgpt open devices in read-only mode when possible.
BUG=chromium-os:12430
TEST=manual
Running "make; make runtests" in src/platform/vboot_refererence will test
this change. Tests for use on a Chromebook are described in the bug report,
but will require a USB or SD card that has a physical write-protect switch.
Change-Id: I16a67bad3b59bec0981f4064f51fb1a29da65a90
Reviewed-on: https://gerrit.chromium.org/gerrit/21474
Tested-by: Bill Richardson <wfrichar@chromium.org>
Commit-Ready: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
-rw-r--r-- | cgpt/cgpt.h | 4 | ||||
-rw-r--r-- | cgpt/cgpt_add.c | 6 | ||||
-rw-r--r-- | cgpt/cgpt_boot.c | 13 | ||||
-rw-r--r-- | cgpt/cgpt_common.c | 5 | ||||
-rw-r--r-- | cgpt/cgpt_create.c | 2 | ||||
-rw-r--r-- | cgpt/cgpt_find.c | 2 | ||||
-rw-r--r-- | cgpt/cgpt_prioritize.c | 2 | ||||
-rw-r--r-- | cgpt/cgpt_repair.c | 2 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 4 | ||||
-rwxr-xr-x | tests/run_cgpt_tests.sh | 23 |
10 files changed, 47 insertions, 16 deletions
diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index 1c809161..6851ded7 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -10,6 +10,7 @@ #endif #define _FILE_OFFSET_BITS 64 +#include <fcntl.h> #include <features.h> #include <stdint.h> #include <stdio.h> @@ -61,7 +62,8 @@ struct drive { }; -int DriveOpen(const char *drive_path, struct drive *drive); +/* mode should be O_RDONLY or O_RDWR */ +int DriveOpen(const char *drive_path, struct drive *drive, int mode); int DriveClose(struct drive *drive, int update_as_needed); int CheckValid(const struct drive *drive); diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index e3e1a483..a3d0fb99 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -39,7 +39,7 @@ int cgpt_set_attributes(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -101,7 +101,7 @@ int cgpt_get_partition_details(CgptAddParams *params) { if (params == NULL) return result; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) { + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) { Error("Unable to open drive: %s\n", params->drive_name); return result; } @@ -183,7 +183,7 @@ int cgpt_add(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { diff --git a/cgpt/cgpt_boot.c b/cgpt/cgpt_boot.c index 33c5471c..f8e712d6 100644 --- a/cgpt/cgpt_boot.c +++ b/cgpt/cgpt_boot.c @@ -21,7 +21,7 @@ int cgpt_get_boot_partition_number(CgptBootParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -65,12 +65,17 @@ int cgpt_boot(CgptBootParams *params) { struct drive drive; int retval = 1; int gpt_retval= 0; + int mode = O_RDONLY; if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (params->create_pmbr || params->partition || params->bootfile) + mode = O_RDWR; + + if (CGPT_OK != DriveOpen(params->drive_name, &drive, mode)) { return CGPT_FAILED; + } if (CGPT_OK != ReadPMBR(&drive)) { Error("Unable to read PMBR\n"); @@ -135,8 +140,8 @@ int cgpt_boot(CgptBootParams *params) { GuidToStr(&drive.pmbr.boot_guid, buf, sizeof(buf)); printf("%s\n", buf); - // Write it all out - if (CGPT_OK == WritePMBR(&drive)) + // Write it all out, if needed. + if (mode == O_RDONLY || CGPT_OK == WritePMBR(&drive)) retval = 0; done: diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index a5a509b1..d69eb670 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -153,10 +153,11 @@ static int Save(const int fd, const uint8_t *buf, // Opens a block device or file, loads raw GPT data from it. +// mode should be O_RDONLY or O_RDWR // // Returns CGPT_FAILED if any error happens. // Returns CGPT_OK if success and information are stored in 'drive'. */ -int DriveOpen(const char *drive_path, struct drive *drive) { +int DriveOpen(const char *drive_path, struct drive *drive, int mode) { struct stat stat; require(drive_path); @@ -165,7 +166,7 @@ int DriveOpen(const char *drive_path, struct drive *drive) { // Clear struct for proper error handling. memset(drive, 0, sizeof(struct drive)); - drive->fd = open(drive_path, O_RDWR | O_LARGEFILE | O_NOFOLLOW); + drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); if (drive->fd == -1) { Error("Can't open %s: %s\n", drive_path, strerror(errno)); return CGPT_FAILED; diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index dc25d8fa..8c899d19 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -15,7 +15,7 @@ int cgpt_create(CgptCreateParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; // Erase the data diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c index 20070209..345c8310 100644 --- a/cgpt/cgpt_find.c +++ b/cgpt/cgpt_find.c @@ -94,7 +94,7 @@ static int do_search(CgptFindParams *params, char *fileName) { GptEntry *entry; char partlabel[GPT_PARTNAME_LEN]; - if (CGPT_OK != DriveOpen(fileName, &drive)) + if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY)) return 0; if (GPT_SUCCESS != GptSanityCheck(&drive.gpt)) { diff --git a/cgpt/cgpt_prioritize.c b/cgpt/cgpt_prioritize.c index 107c00a9..2b3feb06 100644 --- a/cgpt/cgpt_prioritize.c +++ b/cgpt/cgpt_prioritize.c @@ -108,7 +108,7 @@ int cgpt_prioritize(CgptPrioritizeParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { diff --git a/cgpt/cgpt_repair.c b/cgpt/cgpt_repair.c index 96d3fb1c..97beef84 100644 --- a/cgpt/cgpt_repair.c +++ b/cgpt/cgpt_repair.c @@ -15,7 +15,7 @@ int cgpt_repair(CgptRepairParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; int gpt_retval = GptSanityCheck(&drive.gpt); diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index d4170b1c..f0022a9d 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -186,7 +186,7 @@ int cgpt_get_num_non_empty_partitions(CgptShowParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -221,7 +221,7 @@ int cgpt_show(CgptShowParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { diff --git a/tests/run_cgpt_tests.sh b/tests/run_cgpt_tests.sh index ffd6f68d..8b792b4e 100755 --- a/tests/run_cgpt_tests.sh +++ b/tests/run_cgpt_tests.sh @@ -21,6 +21,7 @@ cd "$DIR" echo "Create an empty file to use as the device..." NUM_SECTORS=1000 DEV=fake_dev.bin +rm -f ${DEV} dd if=/dev/zero of=${DEV} conv=notrunc bs=512 count=${NUM_SECTORS} 2>/dev/null @@ -232,6 +233,28 @@ assert_pri 13 13 14 12 15 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 1 1 1 $GPT prioritize -i 1 -f ${DEV} assert_pri 15 15 13 12 14 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 1 1 1 1 0 + +# Now make sure that we don't need write access if we're just looking. +echo "Test read vs read-write access..." +chmod 0444 ${DEV} + +# These should fail +$GPT create -z ${DEV} 2>/dev/null && error +$GPT add -i 2 -P 3 ${DEV} 2>/dev/null && error +$GPT repair ${DEV} 2>/dev/null && error +$GPT prioritize -i 3 ${DEV} 2>/dev/null && error + +# Most 'boot' usage should fail too. +$GPT boot -p ${DEV} 2>/dev/null && error +dd if=/dev/zero of=fake_mbr.bin bs=100 count=1 2>/dev/null +$GPT boot -b fake_mbr.bin ${DEV} 2>/dev/null && error +$GPT boot -i 2 ${DEV} 2>/dev/null && error + +# These should pass +$GPT boot ${DEV} >/dev/null +$GPT show ${DEV} >/dev/null +$GPT find -t kernel ${DEV} >/dev/null + echo "Done." happy "All tests passed." |