Exemplo n.º 1
0
uint16_t
dkcksum_target(struct disklabel *lp)
{
	uint16_t npartitions;

	if (lp->d_magic == DISKMAGIC)
		npartitions = lp->d_npartitions;
	else if (bswap32(lp->d_magic) == DISKMAGIC)
		npartitions = bswap16(lp->d_npartitions);
	else
		npartitions = 0;

	if (npartitions > maxpartitions)
		npartitions = 0;

	return dkcksum_sized(lp, npartitions);
}
Exemplo n.º 2
0
/*
 * Compute checksum for disk label.
 */
u_int
dkcksum(struct disklabel *lp)
{

	return dkcksum_sized(lp, lp->d_npartitions);
}
Exemplo n.º 3
0
static int
validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset)
{
	struct disklabel *lp;
	void *lp_lim;
	int error, swapped;
	uint16_t npartitions;

	error = dkwedge_read(a->pdk, a->vp, label_sector, a->buf, DEV_BSIZE);
	if (error) {
		aprint_error("%s: unable to read BSD disklabel @ %" PRId64
		    ", error = %d\n", a->pdk->dk_name, label_sector, error);
		a->error = error;
		return (SCAN_ERROR);
	}

	/*
	 * We ignore label_offset; this seems to have not been used
	 * consistently in the old code, requiring us to do the search
	 * in the sector.
	 */
	lp = a->buf;
	lp_lim = (char *)a->buf + DEV_BSIZE - DISKLABEL_MINSIZE;
	for (;; lp = (void *)((char *)lp + sizeof(uint32_t))) {
		if ((char *)lp > (char *)lp_lim)
			return (SCAN_CONTINUE);
		label_offset = (size_t)((char *)lp - (char *)a->buf);
		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
			if (lp->d_magic != bswap32(DISKMAGIC) ||
			    lp->d_magic2 != bswap32(DISKMAGIC))
				continue;
			/* Label is in the other byte order. */
			swapped = 1;
		} else
			swapped = 0;

		npartitions = (swapped) ? bswap16(lp->d_npartitions)
					: lp->d_npartitions;

		/* Validate label length. */
		if ((char *)lp + DISKLABEL_SIZE(npartitions) >
		    (char *)a->buf + DEV_BSIZE) {
			aprint_error("%s: BSD disklabel @ "
			    "%" PRId64 "+%zd has bogus partition count (%u)\n",
			    a->pdk->dk_name, label_sector, label_offset,
			    npartitions);
			continue;
		}

		/*
		 * We have validated the partition count.  Checksum it.
		 * Note that we purposefully checksum before swapping
		 * the byte order.
		 */
		if (dkcksum_sized(lp, npartitions) != 0) {
			aprint_error("%s: BSD disklabel @ %" PRId64
			    "+%zd has bad checksum\n", a->pdk->dk_name,
			    label_sector, label_offset);
			continue;
		}
		/* Put the disklabel in the right order. */
		if (swapped)
			swap_disklabel(lp);
		addwedges(a, lp);
		return (SCAN_FOUND);
	}
}