cgpt: repair: handle drive size expansion Currently, if the drive size increases, 'cgpt repair' correctly updates/moves the Secondary GPT header/entries to end of drive, but it does _NOT_ update headers to reflect the new drive size. It 'must' as per section 5.3.2 GPT Header of the UEFI spec [1]: Both the primary and backup GPTs must be valid before an attempt is made to grow the size of a physical volume. [...] As soon as the volume size is increased the backup GPT must be be moved to the end of the volume, and the primary and backup GPT Headers must be updated to reflect the new volume size. That prevents resizing/growing a partition to new available space (as Last Usable LBA is not updated and used in valid range check), and incorrectly points to the old secondary GPT header in primary (as Alternate LBA is not updated). Change CgptRepair() to check for (only) the secondary header and entries modified (i.e., moved to end of drive) and Alternate LBA in the primary header being less than My LBA in secondary header (i.e., confirm secondary header moved), then update both headers. BUG=b:396007118 TEST=`cgpt show -v $DEV | grep -E 'Alternate LBA:|Last LBA:|Sec GPT'` after drive size expansion and `cgpt repair`, then resize partition to all new available space (described below); and `run_cgpt_tests.sh`. BRANCH=none Before: ``` $ dd if=/dev/zero of=drive.img bs=512 count=2048 $ ./build/cgpt/cgpt create drive.img $ ./build/cgpt/cgpt add -b 34 -s $((2048-33-34)) -t data drive.img $ ./build/cgpt/cgpt show -v drive.img 2>&1 \ | grep -E '(Alternate LBA:|Last LBA:|Sec GPT|INVALID|Label)' Alternate LBA: 2047 Last LBA: 2014 34 1981 1 Label: "" 2015 32 Sec GPT table 2047 1 Sec GPT header $ dd if=/dev/zero of=drive.img bs=512 seek=4096 count=0 $ ./build/cgpt/cgpt repair drive.img WARNING: Secondary GPT header is invalid Secondary Entries is updated. Secondary Header is updated. $ ./build/cgpt/cgpt add -b 34 -s $((4096-33-34)) -i 1 drive.img ERROR: Entry outside of valid region ERROR: -i 1 -b 34 -s 4029 $ ./build/cgpt/cgpt show -v drive.img 2>&1 \ | grep -E '(Alternate LBA:|Last LBA:|Sec GPT|INVALID|Label)' Alternate LBA: 2047 Last LBA: 2014 34 1981 1 Label: "" 4063 32 Sec GPT table 4095 1 Sec GPT header ``` After: ``` $ dd if=/dev/zero of=drive.img bs=512 count=2048 $ ./build/cgpt/cgpt create drive.img $ ./build/cgpt/cgpt add -b 34 -s $((2048-33-34)) -t data drive.img $ ./build/cgpt/cgpt show -v drive.img 2>&1 \ | grep -E '(Alternate LBA:|Last LBA:|Sec GPT|INVALID|Label)' Alternate LBA: 2047 Last LBA: 2014 34 1981 1 Label: "" 2015 32 Sec GPT table 2047 1 Sec GPT header $ dd if=/dev/zero of=drive.img bs=512 seek=4096 count=0 $ ./build/cgpt/cgpt repair drive.img WARNING: Secondary GPT header is invalid Secondary Entries is updated. Secondary Header is updated. Drive size expansion detected; headers update required. Primary Header updated. Secondary Header updated. $ ./build/cgpt/cgpt add -b 34 -s $((4096-33-34)) -i 1 drive.img $ ./build/cgpt/cgpt show -v drive.img 2>&1 \ | grep -E '(Alternate LBA:|Last LBA:|Sec GPT|INVALID|Label)' Alternate LBA: 4095 Last LBA: 4062 34 4029 1 Label: "" 4063 32 Sec GPT table 4095 1 Sec GPT header ``` [1] https://uefi.org/sites/default/files/resources/UEFI_Spec_Final_2.11.pdf Change-Id: Iee372277546a4f6b7ef53b4a16df4c93819af031 Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/6258636 Reviewed-by: Tomasz Michalec <tmichalec@google.com> Reviewed-by: Jakub "Kuba" Czapiga <czapiga@google.com> Commit-Queue: Jakub "Kuba" Czapiga <czapiga@google.com>
2 files changed