Check whether key block and preamble fit in padding.
Also add --pad as a valid option to --repack and --verify, so that
kernels with larger-than-normal padding can be verified.
BUG=chromium-os:13720
TEST=see bug 13720
Using the supplied kernel images from the bug,
vbutil_kernel --verify 007 --debug
vbutil_kernel --verify 008 --debug
These should now fail with an error that the key block extends past the padding.
Next, supply a large enough padding size that the key block and
preamble fit. For example:
vbutil_kernel --verify 007 --pad 0x900000 --debug
vbutil_kernel --verify 008 --pad 0x900000 --debug
These should now make it past the padding check, and fail on a
subsequent test (for example, no kernel blob found).
Change-Id: I7ec32b4def29970e302bf922b96d3e206d97fe82
Reviewed-on: http://gerrit.chromium.org/gerrit/810
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c
index 4904610..c2b4a0f 100644
--- a/utility/vbutil_kernel.c
+++ b/utility/vbutil_kernel.c
@@ -129,6 +129,7 @@
" --keyblock <file>"
" Outputs the verified key block, in .keyblock format\n"
" --kloadaddr <address> Assign kernel body load address\n"
+ " --pad <number> Verification padding size in bytes\n"
" --minversion <number> Minimum combined kernel key version\n"
" and kernel version\n"
"\n",
@@ -407,7 +408,7 @@
/* Pull the blob_t stuff out of a prepacked kernel blob file */
-static blob_t *OldBlob(const char* filename) {
+static blob_t *OldBlob(const char* filename, uint64_t pad) {
FILE* fp = NULL;
blob_t *bp = NULL;
struct stat statbuf;
@@ -428,7 +429,7 @@
}
Debug("%s size is 0x%" PRIx64 "\n", filename, statbuf.st_size);
- if (statbuf.st_size < DEFAULT_PADDING) {
+ if (statbuf.st_size < pad) {
error("%s is too small to be a valid kernel blob\n");
return 0;
}
@@ -440,13 +441,13 @@
return 0;
}
- buf = Malloc(DEFAULT_PADDING);
+ buf = Malloc(pad);
if (!buf) {
error("Unable to allocate padding\n");
goto unwind_oldblob;
}
- if (1 != fread(buf, DEFAULT_PADDING, 1, fp)) {
+ if (1 != fread(buf, pad, 1, fp)) {
error("Unable to read header from %s: %s\n", filename, error_fread(fp));
goto unwind_oldblob;
}
@@ -459,6 +460,10 @@
error("key_block_size advances past the end of the blob\n");
goto unwind_oldblob;
}
+ if (now > pad) {
+ error("key_block_size advances past %" PRIu64 " byte padding\n", pad);
+ goto unwind_oldblob;
+ }
/* Skip the preamble */
preamble = (VbKernelPreambleHeader*)(buf + now);
@@ -468,6 +473,10 @@
error("preamble_size advances past the end of the blob\n");
goto unwind_oldblob;
}
+ if (now > pad) {
+ error("preamble_size advances past %" PRIu64 " byte padding\n", pad);
+ goto unwind_oldblob;
+ }
/* Go find the kernel blob */
Debug("kernel blob is at offset 0x%" PRIx64 "\n", now);
@@ -664,7 +673,8 @@
static int Verify(const char* infile, const char* signpubkey, int verbose,
const char* key_block_file,
- uint64_t kernel_body_load_address, uint64_t min_version) {
+ uint64_t kernel_body_load_address, uint64_t min_version,
+ uint64_t pad) {
VbKeyBlockHeader* key_block;
VbKernelPreambleHeader* preamble;
@@ -690,7 +700,7 @@
}
/* Read blob */
- bp = OldBlob(infile);
+ bp = OldBlob(infile, pad);
if (!bp) {
error("Error reading input file\n");
return 1;
@@ -960,7 +970,7 @@
return 1;
}
- bp = OldBlob(oldfile);
+ bp = OldBlob(oldfile, pad);
if (!bp)
return 1;
r = ReplaceConfig(bp, config_file, kernel_body_load_address);
@@ -976,7 +986,7 @@
case OPT_MODE_VERIFY:
return Verify(filename, signpubkey, verbose, key_block_file,
- kernel_body_load_address, min_version);
+ kernel_body_load_address, min_version, pad);
default:
fprintf(stderr,