summaryrefslogtreecommitdiff
path: root/sbin/fdisk
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2021-06-13 13:48:01 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2021-06-13 13:48:01 +0000
commitee5de62685a28f64a776c01433fbfcf707706e78 (patch)
treebcf02986ebae039e29d307416e7f8ec4551c6d01 /sbin/fdisk
parent8bc4a4b16f72978a8467bd1cdcdd826b0351749e (diff)
Don't ignore a GPT that claims the last usable LBA is located
past the address where alternate partition entries would be written. Just adjust the GPT header value (gh_lba_end) to the highest safe value and carry on. Issue encountered in the wild by mlarkin@ while accessing some disk images. ok deraadt@
Diffstat (limited to 'sbin/fdisk')
-rw-r--r--sbin/fdisk/gpt.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c
index 1d9a55288d2..fd0e7ed614e 100644
--- a/sbin/fdisk/gpt.c
+++ b/sbin/fdisk/gpt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpt.c,v 1.27 2021/06/13 13:24:45 krw Exp $ */
+/* $OpenBSD: gpt.c,v 1.28 2021/06/13 13:48:00 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -55,7 +55,7 @@ int
get_header(off_t where)
{
char *secbuf;
- uint64_t partlastlba;
+ uint64_t partlastlba, partslen, lba_end;
int partspersec;
uint32_t orig_gh_csum, new_gh_csum;
@@ -112,10 +112,14 @@ get_header(off_t where)
return (1);
}
- if (letoh64(gh.gh_lba_end) >= DL_GETDSIZE(&dl)) {
- DPRINTF("gpt last usable LBA: expected < %lld, got %llu\n",
- DL_GETDSIZE(&dl), letoh64(gh.gh_lba_end));
- return (1);
+ /* XXX Assume part_num * part_size is multiple of secsize. */
+ partslen = letoh32(gh.gh_part_num) * letoh32(gh.gh_part_size) /
+ dl.d_secsize;
+ lba_end = DL_GETDSIZE(&dl) - partslen - 2;
+ if (letoh64(gh.gh_lba_end) > lba_end) {
+ DPRINTF("gpt last usable LBA: reduced from %llu to %llu\n",
+ letoh64(gh.gh_lba_end), lba_end);
+ gh.gh_lba_end = htole64(lba_end);
}
if (letoh64(gh.gh_lba_start) >= letoh64(gh.gh_lba_end)) {