Commit 9f5bed29 authored by Mike Hibler's avatar Mike Hibler

Bug Fix: fix incorrect usage of "sizeof(blockhdr_t)".

The size of the block header differs depending on the version of the image.
sizeof(blockhdr_t) gives the size of the current version of the header when
the binary was built (V4 currently). This only mattered in two places:

In imagezip, it would have prevented us from creating a backward compatible
V1 image. Probably nobody has done this in 10 years.

In imageunzip, it could prevent relocations from being processed. This only
affected recent builds (V4 format) when attempting to unzip an older
single-partition FreeBSD image (FBSD5 or before). This is unlikely to occur
outside of Utah and only very rarely here.
parent 2acaa56e
......@@ -2012,6 +2012,7 @@ static void
getrelocinfo(const blockhdr_t *hdr)
{
const struct blockreloc *relocs;
int hdrsize = 0;
if (reloctable) {
free(reloctable);
......@@ -2027,8 +2028,23 @@ getrelocinfo(const blockhdr_t *hdr)
exit(1);
}
switch (hdr->magic) {
case COMPRESSED_V1:
hdrsize = sizeof(struct blockhdr_V1);
break;
case COMPRESSED_V2:
case COMPRESSED_V3:
hdrsize = sizeof(struct blockhdr_V2);
break;
case COMPRESSED_V4:
hdrsize = sizeof(struct blockhdr_V4);
break;
default:
fprintf(stderr, "Unrecognized header type 0x%x\n", hdr->magic);
exit(1);
}
relocs = (const struct blockreloc *)
((const char *)&hdr[1] +
((const char *)hdr + hdrsize +
hdr->regioncount * sizeof(struct region));
memcpy(reloctable, relocs, numrelocs * sizeof(struct blockreloc));
}
......@@ -2163,7 +2179,7 @@ reloc_bsdlabel(struct disklabel *label, int reloctype)
} else if (i == RAW_PART && psize != slicesize) {
assert(label->d_partitions[i].p_offset == outputminsec);
fprintf(stderr, "WARNING: raw partition '%c' "
"too small for slice, growing\n", 'a' + i);
"wrong size for slice, fixing\n", 'a' + i);
label->d_partitions[i].p_size = slicesize;
}
}
......
......@@ -2247,8 +2247,8 @@ compress_image(void)
fflush(stderr);
/*
* For version 2 we don't bother to go back and fill in the
* blockcount. Imageunzip and frisbee don't use it. We still
* For version 2 and beyond we don't bother to go back and fill in
* the blockcount. Imageunzip and frisbee don't use it. We still
* do it if creating V1 images and we can seek on the output.
*/
if (compat != COMPRESSED_V1 || !outcanseek)
......@@ -2271,11 +2271,11 @@ compress_image(void)
perror("seeking to read block header");
exit(1);
}
if ((cc = read(outfd, buf, sizeof(blockhdr_t))) < 0) {
if ((cc = read(outfd, buf, sizeof(struct blockhdr_V1))) < 0) {
perror("reading subblock header");
exit(1);
}
assert(cc == sizeof(blockhdr_t));
assert(cc == sizeof(struct blockhdr_V1));
if (lseek(outfd, (off_t) outputoffset, SEEK_SET) < 0) {
perror("seeking to write new block header");
exit(1);
......@@ -2284,11 +2284,11 @@ compress_image(void)
assert(blkhdr->blockindex == i);
blkhdr->blocktotal = count;
if ((cc = devwrite(outfd, buf, sizeof(blockhdr_t))) < 0) {
if ((cc = devwrite(outfd, buf, sizeof(struct blockhdr_V1))) < 0) {
perror("writing new subblock header");
exit(1);
}
assert(cc == sizeof(blockhdr_t));
assert(cc == sizeof(struct blockhdr_V1));
}
return 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment