From 7345db1e037eb7976ae248bad3142f661d7dfa70 Mon Sep 17 00:00:00 2001 From: krw Date: Sun, 13 Jun 2021 13:48:00 +0000 Subject: [PATCH] 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@ --- sbin/fdisk/gpt.c | 16 ++++++++++------ 1 file 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 * Copyright (c) 2015 Kenneth R Westerback @@ -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)) { -- 2.20.1