Beispiel #1
0
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 *
 * lba is the logical block address of the GPT header to test
 * gpt is a GPT header ptr, filled on return.
 * ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to PTEs.
 */
static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,
			gpt_header *pgpt_head, gpt_entry **pgpt_pte)
{
	if (!dev_desc || !pgpt_head) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return 0;
	}

	/* Read GPT Header from device */
	if (dev_desc->block_read(dev_desc->dev, (lbaint_t)lba, 1, pgpt_head)
			!= 1) {
		printf("*** ERROR: Can't read GPT header ***\n");
		return 0;
	}

	if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
		return 0;

	/* Read and allocate Partition Table Entries */
	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
	if (*pgpt_pte == NULL) {
		printf("GPT: Failed to allocate memory for PTE\n");
		return 0;
	}

	if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
		free(*pgpt_pte);
		return 0;
	}

	/* We're done, all's well */
	return 1;
}
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 * @state
 * @lba is the logical block address of the GPT header to test
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 */
static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
			gpt_header **gpt, gpt_entry **ptes)
{
	u32 crc, origcrc;
	u64 lastlba;

	if (!ptes)
		return 0;
	if (!(*gpt = alloc_read_gpt_header(state, lba)))
		return 0;

	/* Check the GUID Partition Table signature */
	if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
		pr_debug("GUID Partition Table Header signature is wrong:"
			 "%lld != %lld\n",
			 (unsigned long long)le64_to_cpu((*gpt)->signature),
			 (unsigned long long)GPT_HEADER_SIGNATURE);
		goto fail;
	}

	/* Check the GUID Partition Table header size is too big */
	if (le32_to_cpu((*gpt)->header_size) >
			bdev_logical_block_size(state->bdev)) {
		pr_debug("GUID Partition Table Header size is too large: %u > %u\n",
			le32_to_cpu((*gpt)->header_size),
			bdev_logical_block_size(state->bdev));
		goto fail;
	}

	/* Check the GUID Partition Table header size is too small */
	if (le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) {
		pr_debug("GUID Partition Table Header size is too small: %u < %zu\n",
			le32_to_cpu((*gpt)->header_size),
			sizeof(gpt_header));
		goto fail;
	}

	/* Check the GUID Partition Table CRC */
	origcrc = le32_to_cpu((*gpt)->header_crc32);
	(*gpt)->header_crc32 = 0;
	crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));

	if (crc != origcrc) {
		pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n",
			 crc, origcrc);
		goto fail;
	}
	(*gpt)->header_crc32 = cpu_to_le32(origcrc);

	/* Check that the my_lba entry points to the LBA that contains
	 * the GUID Partition Table */
	if (le64_to_cpu((*gpt)->my_lba) != lba) {
		pr_debug("GPT my_lba incorrect: %lld != %lld\n",
			 (unsigned long long)le64_to_cpu((*gpt)->my_lba),
			 (unsigned long long)lba);
		goto fail;
	}

	/* Check the first_usable_lba and last_usable_lba are
	 * within the disk.
	 */
	lastlba = last_lba(state->bdev);
	if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
		pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n",
			 (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
			 (unsigned long long)lastlba);
		goto fail;
	}
	if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
		pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n",
			 (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
			 (unsigned long long)lastlba);
		goto fail;
	}

	/* Check that sizeof_partition_entry has the correct value */
	if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
		pr_debug("GUID Partitition Entry Size check failed.\n");
		goto fail;
	}

	if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
		goto fail;

	/* Check the GUID Partition Entry Array CRC */
	crc = efi_crc32((const unsigned char *) (*ptes),
			le32_to_cpu((*gpt)->num_partition_entries) *
			le32_to_cpu((*gpt)->sizeof_partition_entry));

	if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
		pr_debug("GUID Partitition Entry Array CRC check failed.\n");
		goto fail_ptes;
	}

	/* We're done, all's well */
	return 1;

 fail_ptes:
	kfree(*ptes);
	*ptes = NULL;
 fail:
	kfree(*gpt);
	*gpt = NULL;
	if (!force_gpt)
		BUG_ON(1);
	return 0;
}
Beispiel #3
0
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 *
 * lba is the logical block address of the GPT header to test
 * gpt is a GPT header ptr, filled on return.
 * ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to PTEs.
 */
static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
			gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
{
	unsigned char crc32_backup[4] = { 0 };
	unsigned long calc_crc32;
	unsigned long long lastlba;

	if (!dev_desc || !pgpt_head) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return 0;
	}

	/* Read GPT Header from device */
	if (dev_desc->block_read(dev_desc->dev, lba, 1, pgpt_head) != 1) {
		printf("*** ERROR: Can't read GPT header ***\n");
		return 0;
	}

	/* Check the GPT header signature */
	if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
		printf("GUID Partition Table Header signature is wrong:"
			"0x%llX != 0x%llX\n",
			(unsigned long long)le64_to_int(pgpt_head->signature),
			(unsigned long long)GPT_HEADER_SIGNATURE);
		return 0;
	}

	/* Check the GUID Partition Table CRC */
	memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
	memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));

	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
		le32_to_int(pgpt_head->header_size));

	memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));

	if (calc_crc32 != le32_to_int(crc32_backup)) {
		printf("GUID Partition Table Header CRC is wrong:"
			"0x%08lX != 0x%08lX\n",
			le32_to_int(crc32_backup), calc_crc32);
		return 0;
	}

	/* Check that the my_lba entry points to the LBA that contains the GPT */
	if (le64_to_int(pgpt_head->my_lba) != lba) {
		printf("GPT: my_lba incorrect: %llX != %llX\n",
			(unsigned long long)le64_to_int(pgpt_head->my_lba),
			(unsigned long long)lba);
		return 0;
	}

	/* Check the first_usable_lba and last_usable_lba are within the disk. */
	lastlba = (unsigned long long)dev_desc->lba;
	if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
		printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
			le64_to_int(pgpt_head->first_usable_lba), lastlba);
		return 0;
	}
	if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
		printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
			le64_to_int(pgpt_head->last_usable_lba), lastlba);
		return 0;
	}

	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
		le64_to_int(pgpt_head->first_usable_lba),
		le64_to_int(pgpt_head->last_usable_lba), lastlba);

	/* Read and allocate Partition Table Entries */
	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
	if (*pgpt_pte == NULL) {
		printf("GPT: Failed to allocate memory for PTE\n");
		return 0;
	}

	/* Check the GUID Partition Table Entry Array CRC */
	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
		le32_to_int(pgpt_head->num_partition_entries) *
		le32_to_int(pgpt_head->sizeof_partition_entry));

	if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
		printf("GUID Partition Table Entry Array CRC is wrong:"
			"0x%08lX != 0x%08lX\n",
			le32_to_int(pgpt_head->partition_entry_array_crc32),
			calc_crc32);

		if (*pgpt_pte != NULL) {
			free(*pgpt_pte);
		}
		return 0;
	}

	/* We're done, all's well */
	return 1;
}
Beispiel #4
0
Datei: efi.c Projekt: 274914765/C
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 * @bdev
 * @lba is the logical block address of the GPT header to test
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 */
static int
is_gpt_valid(struct block_device *bdev, u64 lba,
         gpt_header **gpt, gpt_entry **ptes)
{
    u32 crc, origcrc;
    u64 lastlba;

    if (!bdev || !gpt || !ptes)
        return 0;
    if (!(*gpt = alloc_read_gpt_header(bdev, lba)))
        return 0;

    /* Check the GUID Partition Table signature */
    if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
        Dprintk("GUID Partition Table Header signature is wrong:"
            "%lld != %lld\n",
            (unsigned long long)le64_to_cpu((*gpt)->signature),
            (unsigned long long)GPT_HEADER_SIGNATURE);
        goto fail;
    }

    /* Check the GUID Partition Table CRC */
    origcrc = le32_to_cpu((*gpt)->header_crc32);
    (*gpt)->header_crc32 = 0;
    crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));

    if (crc != origcrc) {
        Dprintk
            ("GUID Partition Table Header CRC is wrong: %x != %x\n",
             crc, origcrc);
        goto fail;
    }
    (*gpt)->header_crc32 = cpu_to_le32(origcrc);

    /* Check that the my_lba entry points to the LBA that contains
     * the GUID Partition Table */
    if (le64_to_cpu((*gpt)->my_lba) != lba) {
        Dprintk("GPT my_lba incorrect: %lld != %lld\n",
            (unsigned long long)le64_to_cpu((*gpt)->my_lba),
            (unsigned long long)lba);
        goto fail;
    }

    /* Check the first_usable_lba and last_usable_lba are
     * within the disk.
     */
    lastlba = last_lba(bdev);
    if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
        Dprintk("GPT: first_usable_lba incorrect: %lld > %lld\n",
            (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
            (unsigned long long)lastlba);
        goto fail;
    }
    if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
        Dprintk("GPT: last_usable_lba incorrect: %lld > %lld\n",
            (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
            (unsigned long long)lastlba);
        goto fail;
    }

    if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt)))
        goto fail;

    /* Check the GUID Partition Entry Array CRC */
    crc = efi_crc32((const unsigned char *) (*ptes),
            le32_to_cpu((*gpt)->num_partition_entries) *
            le32_to_cpu((*gpt)->sizeof_partition_entry));

    if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
        Dprintk("GUID Partitition Entry Array CRC check failed.\n");
        goto fail_ptes;
    }

    /* We're done, all's well */
    return 1;

 fail_ptes:
    kfree(*ptes);
    *ptes = NULL;
 fail:
    kfree(*gpt);
    *gpt = NULL;
    return 0;
}
Beispiel #5
0
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 * @fd  is an open file descriptor to the whole disk
 * @lba is the logical block address of the GPT header to test
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 */
static int
is_gpt_valid(int fd, uint64_t lba,
             gpt_header ** gpt, gpt_entry ** ptes)
{
	int rc = 0;		/* default to not valid */
	uint32_t crc, origcrc;

	if (!gpt || !ptes)
                return 0;
	if (!(*gpt = alloc_read_gpt_header(fd, lba)))
		return 0;

	/* Check the GUID Partition Table signature */
	if (__le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
		/* 
		   printf("GUID Partition Table Header signature is wrong: %" PRIx64" != %" PRIx64 "\n",
		   __le64_to_cpu((*gpt)->signature), GUID_PT_HEADER_SIGNATURE);
		 */
		free(*gpt);
		*gpt = NULL;
		return rc;
	}

	/* Check the GUID Partition Table Header CRC */
	origcrc = __le32_to_cpu((*gpt)->header_crc32);
	(*gpt)->header_crc32 = 0;
	crc = efi_crc32(*gpt, __le32_to_cpu((*gpt)->header_size));
	if (crc != origcrc) {
		// printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc);
		(*gpt)->header_crc32 = __cpu_to_le32(origcrc);
		free(*gpt);
		*gpt = NULL;
		return 0;
	}
	(*gpt)->header_crc32 = __cpu_to_le32(origcrc);

	/* Check that the my_lba entry points to the LBA
	 * that contains the GPT we read */
	if (__le64_to_cpu((*gpt)->my_lba) != lba) {
		// printf( "my_lba % PRIx64 "x != lba %"PRIx64 "x.\n", __le64_to_cpu((*gpt)->my_lba), lba);
		free(*gpt);
		*gpt = NULL;
		return 0;
	}

	if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
		free(*gpt);
		*gpt = NULL;
		return 0;
	}

	/* Check the GUID Partition Entry Array CRC */
	crc = efi_crc32(*ptes,
                        __le32_to_cpu((*gpt)->num_partition_entries) *
			__le32_to_cpu((*gpt)->sizeof_partition_entry));
	if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
		// printf("GUID Partitition Entry Array CRC check failed.\n");
		free(*gpt);
		*gpt = NULL;
		free(*ptes);
		*ptes = NULL;
		return 0;
	}

	/* We're done, all's well */
	return 1;
}
Beispiel #6
0
/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 * @bdev
 * @lba is the logical block address of the GPT header to test
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 */
static int
is_gpt_valid(struct block_device *bdev, u64 lba,
	     gpt_header **gpt, gpt_entry **ptes)
{
	u32 crc, origcrc;

	if (!bdev || !gpt || !ptes)
		return 0;
	if (!(*gpt = alloc_read_gpt_header(bdev, lba)))
		return 0;

	/* Check the GUID Partition Table signature */
	if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
		Dprintk("GUID Partition Table Header signature is wrong: %"
			PRIx64 " != %" PRIx64 "\n", le64_to_cpu((*gpt)->signature),
			GPT_HEADER_SIGNATURE);
		kfree(*gpt);
		*gpt = NULL;
		return 0;
	}

	/* Check the GUID Partition Table CRC */
	origcrc = le32_to_cpu((*gpt)->header_crc32);
	(*gpt)->header_crc32 = 0;
	crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));

	if (crc != origcrc) {
		Dprintk
		    ("GUID Partition Table Header CRC is wrong: %x != %x\n",
		     crc, origcrc);
		kfree(*gpt);
		*gpt = NULL;
		return 0;
	}
	(*gpt)->header_crc32 = cpu_to_le32(origcrc);

	/* Check that the my_lba entry points to the LBA that contains
	 * the GUID Partition Table */
	if (le64_to_cpu((*gpt)->my_lba) != lba) {
		Dprintk("GPT my_lba incorrect: %" PRIx64 " != %" PRIx64 "\n",
			le64_to_cpu((*gpt)->my_lba), lba);
		kfree(*gpt);
		*gpt = NULL;
		return 0;
	}

	if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt))) {
		kfree(*gpt);
		*gpt = NULL;
		return 0;
	}

	/* Check the GUID Partition Entry Array CRC */
	crc = efi_crc32((const unsigned char *) (*ptes),
			le32_to_cpu((*gpt)->num_partition_entries) *
			le32_to_cpu((*gpt)->sizeof_partition_entry));

	if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
		Dprintk("GUID Partitition Entry Array CRC check failed.\n");
		kfree(*gpt);
		*gpt = NULL;
		kfree(*ptes);
		*ptes = NULL;
		return 0;
	}

	/* We're done, all's well */
	return 1;
}