summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/efi_partition.h1
-rw-r--r--lib/libefi/rdwr_efi.c25
2 files changed, 17 insertions, 9 deletions
diff --git a/include/sys/efi_partition.h b/include/sys/efi_partition.h
index ff38df5e7..e75e45a6b 100644
--- a/include/sys/efi_partition.h
+++ b/include/sys/efi_partition.h
@@ -35,6 +35,7 @@ extern "C" {
* GUID Partition Table Header
*/
+#define EFI_MIN_LABEL_SIZE 92
#define EFI_LABEL_SIZE 512
#define LEN_EFI_PAD (EFI_LABEL_SIZE - \
((5 * sizeof (diskaddr_t)) + \
diff --git a/lib/libefi/rdwr_efi.c b/lib/libefi/rdwr_efi.c
index 2af0c4e2e..43a5310a3 100644
--- a/lib/libefi/rdwr_efi.c
+++ b/lib/libefi/rdwr_efi.c
@@ -541,16 +541,22 @@ check_label(int fd, dk_efi_t *dk_ioc)
*/
crc = efi->efi_gpt_HeaderCRC32;
efi->efi_gpt_HeaderCRC32 = 0;
+ len_t headerSize = (len_t)LE_32(efi->efi_gpt_HeaderSize);
- if (((len_t)LE_32(efi->efi_gpt_HeaderSize) > dk_ioc->dki_length) ||
- crc != LE_32(efi_crc32((unsigned char *)efi,
- LE_32(efi->efi_gpt_HeaderSize)))) {
+ if(headerSize < EFI_MIN_LABEL_SIZE || headerSize > EFI_LABEL_SIZE) {
+ if (efi_debug)
+ (void) fprintf(stderr,
+ "Invalid EFI HeaderSize %llu. Assuming %d.\n",
+ headerSize, EFI_MIN_LABEL_SIZE);
+ }
+
+ if ((headerSize > dk_ioc->dki_length) ||
+ crc != LE_32(efi_crc32((unsigned char *)efi, headerSize))) {
if (efi_debug)
(void) fprintf(stderr,
"Bad EFI CRC: 0x%x != 0x%x\n",
- crc,
- LE_32(efi_crc32((unsigned char *)efi,
- sizeof (struct efi_gpt))));
+ crc, LE_32(efi_crc32((unsigned char *)efi,
+ headerSize)));
return (VT_EINVAL);
}
@@ -1152,7 +1158,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
/* stuff user's input into EFI struct */
efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
- efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
+ efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt) - LEN_EFI_PAD);
efi->efi_gpt_Reserved1 = 0;
efi->efi_gpt_MyLBA = LE_64(1ULL);
efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
@@ -1221,7 +1227,8 @@ efi_write(int fd, struct dk_gpt *vtoc)
LE_32(efi_crc32((unsigned char *)efi_parts,
vtoc->efi_nparts * (int)sizeof (struct efi_gpe)));
efi->efi_gpt_HeaderCRC32 =
- LE_32(efi_crc32((unsigned char *)efi, sizeof (struct efi_gpt)));
+ LE_32(efi_crc32((unsigned char *)efi,
+ LE_32(efi->efi_gpt_HeaderSize)));
if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
free(dk_ioc.dki_data);
@@ -1274,7 +1281,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
efi->efi_gpt_HeaderCRC32 = 0;
efi->efi_gpt_HeaderCRC32 =
LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data,
- sizeof (struct efi_gpt)));
+ LE_32(efi->efi_gpt_HeaderSize)));
if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
if (efi_debug) {