gpt: use inline functions for checking status bits

This should prevent bugs like 6078f836 and 4268f3da.
This commit is contained in:
Michael Marineau 2016-09-20 12:43:01 -07:00
parent 4268f3da52
commit 3dda6a863a
4 changed files with 39 additions and 13 deletions

View file

@ -91,7 +91,7 @@ grub_find_next (const char *disk_name,
if (!gpt)
goto done;
if ((gpt->status & GRUB_GPT_BOTH_VALID) != GRUB_GPT_BOTH_VALID)
if (!grub_gpt_both_valid(gpt))
if (grub_gpt_repair (dev->disk, gpt))
goto done;

View file

@ -65,16 +65,16 @@ grub_cmd_gptrepair (grub_command_t cmd __attribute__ ((unused)),
if (!gpt)
goto done;
if ((gpt->status & GRUB_GPT_BOTH_VALID) == GRUB_GPT_BOTH_VALID)
if (grub_gpt_both_valid (gpt))
{
grub_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name);
goto done;
}
if ((gpt->status & GRUB_GPT_PRIMARY_VALID) != GRUB_GPT_PRIMARY_VALID)
if (!grub_gpt_primary_valid (gpt))
grub_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name);
if ((gpt->status & GRUB_GPT_BACKUP_VALID) != GRUB_GPT_BACKUP_VALID)
if (!grub_gpt_backup_valid (gpt))
grub_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name);
if (grub_gpt_repair (dev->disk, gpt))

View file

@ -631,10 +631,15 @@ grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt)
if (grub_gpt_check_primary (gpt))
return grub_error (GRUB_ERR_BUG, "Generated invalid GPT primary header");
gpt->status |= (GRUB_GPT_PRIMARY_HEADER_VALID |
GRUB_GPT_PRIMARY_ENTRIES_VALID);
if (grub_gpt_check_backup (gpt))
return grub_error (GRUB_ERR_BUG, "Generated invalid GPT backup header");
gpt->status |= GRUB_GPT_BOTH_VALID;
gpt->status |= (GRUB_GPT_BACKUP_HEADER_VALID |
GRUB_GPT_BACKUP_ENTRIES_VALID);
grub_dprintf ("gpt", "repairing GPT for %s successful\n", disk->name);
return GRUB_ERR_NONE;
@ -696,7 +701,7 @@ grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt)
{
/* TODO: update/repair protective MBRs too. */
if ((gpt->status & GRUB_GPT_BOTH_VALID) != GRUB_GPT_BOTH_VALID)
if (!grub_gpt_both_valid (gpt))
return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);

View file

@ -161,13 +161,6 @@ typedef enum grub_gpt_status
GRUB_GPT_BACKUP_ENTRIES_VALID = 0x20,
} grub_gpt_status_t;
#define GRUB_GPT_MBR_VALID (GRUB_GPT_PROTECTIVE_MBR|GRUB_GPT_HYBRID_MBR)
#define GRUB_GPT_PRIMARY_VALID \
(GRUB_GPT_PRIMARY_HEADER_VALID|GRUB_GPT_PRIMARY_ENTRIES_VALID)
#define GRUB_GPT_BACKUP_VALID \
(GRUB_GPT_BACKUP_HEADER_VALID|GRUB_GPT_BACKUP_ENTRIES_VALID)
#define GRUB_GPT_BOTH_VALID (GRUB_GPT_PRIMARY_VALID|GRUB_GPT_BACKUP_VALID)
/* UEFI requires the entries table to be at least 16384 bytes for a
* total of 128 entries given the standard 128 byte entry size. */
#define GRUB_GPT_DEFAULT_ENTRIES_SIZE 16384
@ -197,6 +190,34 @@ struct grub_gpt
};
typedef struct grub_gpt *grub_gpt_t;
/* Helpers for checking the gpt status field. */
static inline int
grub_gpt_mbr_valid (grub_gpt_t gpt)
{
return ((gpt->status & GRUB_GPT_PROTECTIVE_MBR) ||
(gpt->status & GRUB_GPT_HYBRID_MBR));
}
static inline int
grub_gpt_primary_valid (grub_gpt_t gpt)
{
return ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) &&
(gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID));
}
static inline int
grub_gpt_backup_valid (grub_gpt_t gpt)
{
return ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) &&
(gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID));
}
static inline int
grub_gpt_both_valid (grub_gpt_t gpt)
{
return grub_gpt_primary_valid (gpt) && grub_gpt_backup_valid (gpt);
}
/* Translate GPT sectors to GRUB's 512 byte block addresses. */
static inline grub_disk_addr_t
grub_gpt_sector_to_addr (grub_gpt_t gpt, grub_uint64_t sector)