Ejemplo n.º 1
0
static int gpt_check_hdr_crc(const struct disk_info * const diskinfo, struct disk_gpt_header **_gh)
{
    struct disk_gpt_header *gh = *_gh;
    uint64_t lba_alt;
    uint32_t hold_crc32;

    hold_crc32 = gh->chksum;
    gh->chksum = 0;
    if (!valid_crc(hold_crc32, (const uint8_t *)gh, gh->hdr_size)) {
	warn("Primary GPT header checksum invalid.");
	/* retry with backup */
	lba_alt = gh->lba_alt;
	free(gh);
	if (!(gh = *_gh = disk_read_sectors(diskinfo, lba_alt, 1))) {
	    error("Couldn't read backup GPT header.");
	    return -1;
	}
	hold_crc32 = gh->chksum;
	gh->chksum = 0;
	if (!valid_crc(hold_crc32, (const uint8_t *)gh, gh->hdr_size)) {
	    error("Secondary GPT header checksum invalid.");
	    return -1;
	}
    }
    /* restore old checksum */
    gh->chksum = hold_crc32;

    return 0;
}
Ejemplo n.º 2
0
	bool hdlc16::valid_frame( void )
	{
	size_t bitcnt = bitbuf.size();
	//this can be extended to work for odd HDLC bitframes later
	if( bitcnt % 8 != 0 )
		{
		return false;
		}
	if( bitcnt < 32 )
		{
		return false;
		}
	if( last_8_bits != HDLC_FRAMER )
		{
		return false;
		}
	if( !valid_crc() )
		{
		return false;
		}
	return true;
	}
Ejemplo n.º 3
0
static struct disk_gpt_part_entry *try_gpt_list(const struct disk_info *di, const struct disk_gpt_header *gpth, int alt)
{
    int pri = gpth->lba_cur < gpth->lba_alt;
    const char *desc = alt ? "alternative" : "main";
    struct disk_gpt_part_entry *gptl;
    char errbuf[64];
    uint64_t gpt_lsiz;	    /* size of GPT partition list in bytes */
    uint64_t gpt_lcnt;	    /* size of GPT partition in sectors */
    uint64_t gpt_loff;	    /* offset to GPT partition list in sectors */

    gpt_lsiz = (uint64_t)gpth->part_size * gpth->part_count;
    gpt_lcnt = (gpt_lsiz + di->bps - 1) / di->bps;
    if (!alt) {
	/* prefer header value for partition table if not asking for alternative */
	gpt_loff = gpth->lba_table;
    } else {
	/* try to read alternative, we have to calculate its position */
	if (!pri)
	    gpt_loff = gpth->lba_alt + 1;
	else
	    gpt_loff = gpth->lba_alt - gpt_lcnt;
    }

    gptl = disk_read_sectors(di, gpt_loff, gpt_lcnt);
    if (!gptl) {
	sprintf(errbuf, "Unable to read %s GPT partition list.", desc);
	try_gpt_we(errbuf, alt);
	return NULL;
    }
    if (!valid_crc(gpth->table_chksum, (const uint8_t *)gptl, gpt_lsiz)) {
	sprintf(errbuf, "Invalid checksum of %s GPT partition list.", desc);
	try_gpt_we(errbuf, alt);
	free(gptl);
	return NULL;
    }
    return gptl;
}
Ejemplo n.º 4
0
/* pi_begin() - validate and and get proper iterator for a disk described by di */
struct part_iter *pi_begin(const struct disk_info *di, int flags)
{
    int gptprot, ret = -1;
    struct part_iter *iter;
    struct disk_dos_mbr *mbr = NULL;
    struct disk_gpt_header *gpth = NULL;
    struct disk_gpt_part_entry *gptl = NULL;

    /* Preallocate iterator */
    if (!(iter = pi_alloc()))
	goto bail;

    /* Read MBR */
    if (!(mbr = disk_read_sectors(di, 0, 1))) {
	error("Couldn't read the first disk sector.");
	goto bail;
    }

    /* Check for MBR magic */
    if (mbr->sig != disk_mbr_sig_magic) {
	warn("No MBR magic, treating disk as raw.");
	/* looks like RAW */
	ret = pi_ctor(iter, di, flags);
	goto bail;
    }

    /* Check for GPT protective MBR */
    gptprot = 0;
    for (size_t i = 0; i < 4; i++)
	gptprot |= (mbr->table[i].ostype == 0xEE);
    if (gptprot && !(flags & PIF_PREFMBR)) {
	if (!(gpth = disk_read_sectors(di, 1, 1))) {
	    error("Couldn't read potential GPT header.");
	    goto bail;
	}
    }

    if (gpth && gpth->rev.uint32 == 0x00010000 &&
	    !memcmp(gpth->sig, disk_gpt_sig_magic, sizeof gpth->sig)) {
	/* looks like GPT v1.0 */
	uint64_t gpt_loff;	    /* offset to GPT partition list in sectors */
	uint64_t gpt_lsiz;	    /* size of GPT partition list in bytes */
	uint64_t gpt_lcnt;	    /* size of GPT partition in sectors */
#ifdef DEBUG
	dprintf("Looks like a GPT v1.0 disk.\n");
	disk_gpt_header_dump(gpth);
#endif
	/* Verify checksum, fallback to backup, then bail if invalid */
	if (gpt_check_hdr_crc(di, &gpth))
	    goto bail;

	gpt_loff = gpth->lba_table;
	gpt_lsiz = (uint64_t)gpth->part_size * gpth->part_count;
	gpt_lcnt = (gpt_lsiz + di->bps - 1) / di->bps;

	/*
	 * disk_read_sectors allows reading of max 255 sectors, so we use
	 * it as a sanity check base. EFI doesn't specify max (AFAIK).
	 * Apart from that, some extensive sanity checks.
	 */
	if (!(flags & PIF_RELAX) && (
		!gpt_loff || !gpt_lsiz || gpt_lcnt > 255u ||
		gpth->lba_first_usable > gpth->lba_last_usable ||
		!sane(gpt_loff, gpt_lcnt) ||
		gpt_loff + gpt_lcnt > gpth->lba_first_usable ||
		!sane(gpth->lba_last_usable, gpt_lcnt) ||
		gpth->lba_last_usable + gpt_lcnt >= gpth->lba_alt ||
		gpth->lba_alt >= di->lbacnt ||
		gpth->part_size < sizeof *gptl)) {
	    error("Invalid GPT header's values.");
	    goto bail;
	}
	if (!(gptl = disk_read_sectors(di, gpt_loff, gpt_lcnt))) {
	    error("Couldn't read GPT partition list.");
	    goto bail;
	}
	/* Check array checksum(s). */
	if (!valid_crc(gpth->table_chksum, (const uint8_t *)gptl, (unsigned int)gpt_lsiz)) {
	    warn("Checksum of the main GPT partition list is invalid, trying backup.");
	    free(gptl);
	    /* secondary array directly precedes secondary header */
	    if (!(gptl = disk_read_sectors(di, gpth->lba_alt - gpt_lcnt, gpt_lcnt))) {
		error("Couldn't read backup GPT partition list.");
		goto bail;
	    }
	    if (!valid_crc(gpth->table_chksum, (const uint8_t *)gptl, gpt_lsiz)) {
		error("Checksum of the backup GPT partition list is invalid, giving up.");
		goto bail;
	    }
	}
	/* looks like GPT */
	ret = pi_gpt_ctor(iter, di, flags, gpth, gptl);
    } else {
	/* looks like MBR */
	ret = pi_dos_ctor(iter, di, flags, mbr);
    }
bail:
    if (ret < 0)
	free(iter);
    free(mbr);
    free(gpth);
    free(gptl);

    return iter;
}