gpt: record size of of the entries table

The size of the entries table will be needed later when writing it back
to disk. Restructure the entries reading code to flow a little better.
This commit is contained in:
Michael Marineau 2014-10-18 16:46:17 -07:00
parent 3b2674aef7
commit 4dd009a6fb
2 changed files with 27 additions and 31 deletions

View file

@ -153,7 +153,7 @@ grub_gpt_read_backup (grub_disk_t disk, grub_gpt_t gpt)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static struct grub_gpt_partentry * static grub_err_t
grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt, grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
struct grub_gpt_header *header) struct grub_gpt_header *header)
{ {
@ -173,6 +173,10 @@ grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
goto fail; goto fail;
} }
/* Double check that the header was validated properly. */
if (entries_size < GRUB_GPT_DEFAULT_ENTRIES_SIZE)
return grub_error (GRUB_ERR_BUG, "invalid GPT entries table size");
entries = grub_malloc (entries_size); entries = grub_malloc (entries_size);
if (!entries) if (!entries)
goto fail; goto fail;
@ -197,19 +201,21 @@ grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
} }
grub_free (crc32_context); grub_free (crc32_context);
return entries; grub_free (gpt->entries);
gpt->entries = entries;
gpt->entries_size = entries_size;
return GRUB_ERR_NONE;
fail: fail:
grub_free (entries); grub_free (entries);
grub_free (crc32_context); grub_free (crc32_context);
return NULL; return grub_errno;
} }
grub_gpt_t grub_gpt_t
grub_gpt_read (grub_disk_t disk) grub_gpt_read (grub_disk_t disk)
{ {
grub_gpt_t gpt; grub_gpt_t gpt;
struct grub_gpt_partentry *backup_entries;
gpt = grub_zalloc (sizeof (*gpt)); gpt = grub_zalloc (sizeof (*gpt));
if (!gpt) if (!gpt)
@ -241,36 +247,23 @@ grub_gpt_read (grub_disk_t disk)
else else
goto fail; goto fail;
/* Same error handling scheme for the entry tables. */ /* Similarly, favor the value or error from the primary table. */
gpt->entries = grub_gpt_read_entries (disk, gpt, &gpt->primary); if (gpt->status & GRUB_GPT_BACKUP_HEADER_VALID &&
if (!gpt->entries) !grub_gpt_read_entries (disk, gpt, &gpt->backup))
{
grub_error_push ();
backup_entries = grub_gpt_read_entries (disk, gpt, &gpt->backup);
grub_error_pop ();
}
else
{
gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID;
backup_entries = grub_gpt_read_entries (disk, gpt, &gpt->backup);
}
if (backup_entries)
{
gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID; gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID;
if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID) grub_errno = GRUB_ERR_NONE;
grub_free (backup_entries); if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID &&
else !grub_gpt_read_entries (disk, gpt, &gpt->primary))
gpt->entries = backup_entries; gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID;
}
if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID || if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID ||
gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID) gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID)
{
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
else
goto fail;
return gpt; return gpt;
}
fail: fail:
grub_gpt_free (gpt); grub_gpt_free (gpt);

View file

@ -106,7 +106,9 @@ typedef enum grub_gpt_status
/* UEFI requires the entries table to be at least 16384 bytes for a /* UEFI requires the entries table to be at least 16384 bytes for a
* total of 128 entries given the standard 128 byte entry size. */ * total of 128 entries given the standard 128 byte entry size. */
#define GRUB_GPT_DEFAULT_ENTRIES_LENGTH 128 #define GRUB_GPT_DEFAULT_ENTRIES_SIZE 16384
#define GRUB_GPT_DEFAULT_ENTRIES_LENGTH \
(GRUB_GPT_DEFAULT_ENTRIES_SIZE / sizeof (struct grub_gpt_partentry))
struct grub_gpt struct grub_gpt
{ {
@ -122,6 +124,7 @@ struct grub_gpt
/* Only need one entries table, on disk both copies are identical. */ /* Only need one entries table, on disk both copies are identical. */
struct grub_gpt_partentry *entries; struct grub_gpt_partentry *entries;
grub_size_t entries_size;
/* Logarithm of sector size, in case GPT and disk driver disagree. */ /* Logarithm of sector size, in case GPT and disk driver disagree. */
unsigned int log_sector_size; unsigned int log_sector_size;