X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=lib%2Flibefi%2Frdwr_efi.c;h=43a5310a318a016aa03c4f1858d1c7d464a31abf;hb=ab26409db753bb087842ab6f1af943f3386c764f;hp=da71e3486c2270886a3621403cd9ddb17b4ba29b;hpb=d603ed6c278f9c25b17ba8e75e9bce6e5d715ac0;p=zfs.git diff --git a/lib/libefi/rdwr_efi.c b/lib/libefi/rdwr_efi.c index da71e34..43a5310 100644 --- a/lib/libefi/rdwr_efi.c +++ b/lib/libefi/rdwr_efi.c @@ -269,19 +269,12 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc) struct uuid uuid; struct dk_cinfo dki_info; - if (read_disk_info(fd, &capacity, &lbsize) != 0) { - if (efi_debug) - (void) fprintf(stderr, - "couldn't read disk information\n"); + if (read_disk_info(fd, &capacity, &lbsize) != 0) return (-1); - } + #if defined(__linux__) - if (efi_get_info(fd, &dki_info) != 0) { - if (efi_debug) - (void) fprintf(stderr, - "couldn't read disk information\n"); + if (efi_get_info(fd, &dki_info) != 0) return (-1); - } if (dki_info.dki_partition != 0) return (-1); @@ -548,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(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 (((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 > 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); } @@ -1159,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); @@ -1228,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); @@ -1281,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) {