summaryrefslogtreecommitdiffstats
path: root/src/partgpt.c
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2012-12-08 18:00:49 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2012-12-08 18:00:49 +0100
commit4ab4b390670703606b43791b2a03e3cbc1d56378 (patch)
tree5958a142b9f68663ab54d90951e47345412fa6bd /src/partgpt.c
parent7521a455084d1472e9d00949dcef415fcc0246a9 (diff)
Detect alternate EFI GPT
Diffstat (limited to 'src/partgpt.c')
-rw-r--r--src/partgpt.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/partgpt.c b/src/partgpt.c
index 6073f0c..1b60c36 100644
--- a/src/partgpt.c
+++ b/src/partgpt.c
@@ -139,7 +139,7 @@ arch_fnct_t arch_gpt=
.is_part_known=&is_part_known_gpt
};
-list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader)
+static list_part_t *read_part_gpt_aux(disk_t *disk_car, const int verbose, const int saveheader, const uint64_t hdr_lba)
{
struct gpt_hdr *gpt;
struct gpt_ent* gpt_entries;
@@ -149,8 +149,8 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe
uint64_t gpt_entries_offset;
gpt=(struct gpt_hdr*)MALLOC(disk_car->sector_size);
- screen_buffer_reset();
- if((unsigned)disk_car->pread(disk_car, gpt, disk_car->sector_size, disk_car->sector_size) != disk_car->sector_size)
+ if((unsigned)disk_car->pread(disk_car, gpt, disk_car->sector_size,
+ hdr_lba * disk_car->sector_size) != disk_car->sector_size)
{
free(gpt);
return NULL;
@@ -167,7 +167,9 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe
log_info("hdr_lba_self=%llu\n", (long long unsigned)le64(gpt->hdr_lba_self));
log_info("hdr_lba_alt=%llu (expected %llu)\n",
(long long unsigned)le64(gpt->hdr_lba_alt),
- (long long unsigned)((disk_car->disk_size-1)/disk_car->sector_size));
+ (hdr_lba==1?
+ (long long unsigned)((disk_car->disk_size-1)/disk_car->sector_size):
+ 1));
log_info("hdr_lba_start=%llu\n", (long long unsigned)le64(gpt->hdr_lba_start));
log_info("hdr_lba_end=%llu\n", (long long unsigned)le64(gpt->hdr_lba_end));
log_info("hdr_lba_table=%llu\n",
@@ -196,7 +198,7 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe
}
gpt->hdr_crc_self=le32(origcrc);
}
- if(le64(gpt->hdr_lba_self)!=1)
+ if(le64(gpt->hdr_lba_self)!=hdr_lba)
{
screen_buffer_add("Bad GPT partition, invalid LBA self location.\n");
free(gpt);
@@ -239,12 +241,15 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe
return NULL;
}
gpt_entries_offset=(uint64_t)le64(gpt->hdr_lba_table) * disk_car->sector_size;
- if((uint64_t) le64(gpt->hdr_lba_self) + le32(gpt->hdr_size) - 1 >= gpt_entries_offset ||
- gpt_entries_offset >= le64(gpt->hdr_lba_start) * disk_car->sector_size)
+ if(hdr_lba==1)
{
- screen_buffer_add( "GPT: The primary GUID Partition Entry array must be located after the primary GUID Partition Table Header and end before the FirstUsableLBA.\n");
- free(gpt);
- return NULL;
+ if((uint64_t) le64(gpt->hdr_lba_self) + le32(gpt->hdr_size) - 1 >= gpt_entries_offset ||
+ gpt_entries_offset >= le64(gpt->hdr_lba_start) * disk_car->sector_size)
+ {
+ screen_buffer_add( "GPT: The primary GUID Partition Entry array must be located after the primary GUID Partition Table Header and end before the FirstUsableLBA.\n");
+ free(gpt);
+ return NULL;
+ }
}
gpt_entries=(struct gpt_ent*)MALLOC(gpt_entries_size);
@@ -298,6 +303,19 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe
return new_list_part;
}
+list_part_t *read_part_gpt(disk_t *disk, const int verbose, const int saveheader)
+{
+ list_part_t *list_part;
+ screen_buffer_reset();
+ if((list_part=read_part_gpt_aux(disk, verbose, saveheader, 1))!=NULL)
+ return list_part;
+ screen_buffer_add( "Trying alternate GPT\n");
+ list_part=read_part_gpt_aux(disk, verbose, saveheader,
+ (disk->disk_size-1)/disk->sector_size);
+ screen_buffer_to_log();
+ return list_part;
+}
+
static list_part_t *init_part_order_gpt(const disk_t *disk_car, list_part_t *list_part)
{
list_part_t *element;