diff options
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/stand/efiboot/efidev.c | 42 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/softraid.c | 42 |
2 files changed, 47 insertions, 37 deletions
diff --git a/sys/arch/amd64/stand/efiboot/efidev.c b/sys/arch/amd64/stand/efiboot/efidev.c index 62dd84b7f11..e6bd1014305 100644 --- a/sys/arch/amd64/stand/efiboot/efidev.c +++ b/sys/arch/amd64/stand/efiboot/efidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efidev.c,v 1.14 2015/12/24 21:37:25 krw Exp $ */ +/* $OpenBSD: efidev.c,v 1.15 2016/01/03 15:01:31 krw Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -292,14 +292,14 @@ findopenbsd_gpt(efi_diskinfo_t ed, const char **err) { EFI_STATUS status; struct gpt_header gh; - int i, part; + int i, part, found; uint64_t lba; uint32_t orig_csum, new_csum; uint32_t ghsize, ghpartsize, ghpartnum, ghpartspersec; + uint32_t gpsectors; const char openbsd_uuid_code[] = GPT_UUID_OPENBSD; + struct gpt_partition gp; static struct uuid *openbsd_uuid = NULL, openbsd_uuid_space; - static struct gpt_partition - gp[NGPTPARTITIONS]; static u_char buf[4096]; /* Prepare OpenBSD UUID */ @@ -363,28 +363,32 @@ findopenbsd_gpt(efi_diskinfo_t ed, const char **err) ghpartsize = letoh32(gh.gh_part_size); ghpartspersec = ed->blkio->Media->BlockSize / ghpartsize; ghpartnum = letoh32(gh.gh_part_num); - for (i = 0; i < (ghpartnum + ghpartspersec - 1) / ghpartspersec; - i++, lba++) { + gpsectors = (ghpartnum + ghpartspersec - 1) / ghpartspersec; + new_csum = crc32(0L, Z_NULL, 0); + found = 0; + for (i = 0; i < gpsectors; i++, lba++) { status = efid_io(F_READ, ed, EFI_SECTOBLK(ed, lba), EFI_BLKSPERSEC(ed), buf); if (EFI_ERROR(status)) { *err = "Disk I/O Error"; return (-1); } - memcpy(gp + i * ghpartspersec, buf, - ghpartspersec * sizeof(struct gpt_partition)); - } - new_csum = crc32(0, (unsigned char *)&gp, ghpartnum * ghpartsize); - if (new_csum != letoh32(gh.gh_part_csum)) { - *err = "bad GPT partitions checksum\n"; - return (-1); - } - - for (part = 0; part < ghpartnum; part++) { - if (memcmp(&gp[part].gp_type, openbsd_uuid, - sizeof(struct uuid)) == 0) - return letoh64(gp[part].gp_lba_start); + for (part = 0; part < ghpartspersec; part++) { + if (ghpartnum == 0) + break; + new_csum = crc32(new_csum, buf + part * sizeof(gp), + sizeof(gp)); + ghpartnum--; + if (found) + continue; + memcpy(&gp, buf + part * sizeof(gp), sizeof(gp)); + if (memcmp(&gp.gp_type, openbsd_uuid, + sizeof(struct uuid)) == 0) + found = 1; + } } + if (found && new_csum == letoh32(gh.gh_part_csum)) + return letoh64(gp.gp_lba_start); return (-1); } diff --git a/sys/arch/amd64/stand/libsa/softraid.c b/sys/arch/amd64/stand/libsa/softraid.c index d10b514e3c4..747bfda0c29 100644 --- a/sys/arch/amd64/stand/libsa/softraid.c +++ b/sys/arch/amd64/stand/libsa/softraid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid.c,v 1.21 2015/12/24 21:37:25 krw Exp $ */ +/* $OpenBSD: softraid.c,v 1.22 2016/01/03 15:01:31 krw Exp $ */ /* * Copyright (c) 2012 Joel Sing <jsing@openbsd.org> @@ -438,15 +438,15 @@ static uint64_t findopenbsd_gpt(struct sr_boot_volume *bv) { struct gpt_header gh; - int i, part; + int i, part, found; uint64_t lba; uint32_t orig_csum, new_csum; uint32_t ghsize, ghpartsize, ghpartnum, ghpartspersec; + uint32_t gpsectors; const char openbsd_uuid_code[] = GPT_UUID_OPENBSD; + struct gpt_partition gp; static struct uuid *openbsd_uuid = NULL, openbsd_uuid_space; - static struct gpt_partition - gp[NGPTPARTITIONS]; - static u_char buf[4096]; + static u_char buf[DEV_BSIZE]; /* Prepare OpenBSD UUID */ if (openbsd_uuid == NULL) { @@ -491,21 +491,27 @@ findopenbsd_gpt(struct sr_boot_volume *bv) ghpartsize = letoh32(gh.gh_part_size); ghpartspersec = DEV_BSIZE / ghpartsize; ghpartnum = letoh32(gh.gh_part_num); - for (i = 0; i < (ghpartnum + ghpartspersec - 1) / ghpartspersec; - i++, lba++) { + gpsectors = (ghpartnum + ghpartspersec - 1) / ghpartspersec; + new_csum = crc32(0L, Z_NULL, 0); + found = 0; + for (i = 0; i < gpsectors; i++, lba++) { sr_strategy(bv, F_READ, lba, DEV_BSIZE, buf, NULL); - memcpy(gp + i * ghpartspersec, buf, - ghpartspersec * sizeof(struct gpt_partition)); - } - new_csum = crc32(0, (unsigned char *)&gp, ghpartnum * ghpartsize); - if (new_csum != letoh32(gh.gh_part_csum)) - return (-1); - - for (part = 0; part < ghpartnum; part++) { - if (memcmp(&gp[part].gp_type, openbsd_uuid, - sizeof(struct uuid)) == 0) - return letoh64(gp[part].gp_lba_start); + for (part = 0; part < ghpartspersec; part++) { + if (ghpartnum == 0) + break; + new_csum = crc32(new_csum, buf + part * sizeof(gp), + sizeof(gp)); + ghpartnum--; + if (found) + continue; + memcpy(&gp, buf + part * sizeof(gp), sizeof(gp)); + if (memcmp(&gp.gp_type, openbsd_uuid, + sizeof(struct uuid)) == 0) + found = 1; + } } + if (found && new_csum == letoh32(gh.gh_part_csum)) + return letoh64(gp.gp_lba_start); return (-1); } |