OLD | NEW |
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 * | 4 * |
5 * Verified boot kernel utility | 5 * Verified boot kernel utility |
6 */ | 6 */ |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <getopt.h> | 9 #include <getopt.h> |
10 #include <inttypes.h> /* For PRIu64 */ | 10 #include <inttypes.h> /* For PRIu64 */ |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 if (!opt_debug) | 121 if (!opt_debug) |
122 return; | 122 return; |
123 | 123 |
124 va_list ap; | 124 va_list ap; |
125 va_start(ap, format); | 125 va_start(ap, format); |
126 fprintf(stderr, "DEBUG: "); | 126 fprintf(stderr, "DEBUG: "); |
127 vfprintf(stderr, format, ap); | 127 vfprintf(stderr, format, ap); |
128 va_end(ap); | 128 va_end(ap); |
129 } | 129 } |
130 | 130 |
| 131 /* Return an explanation when fread() fails. */ |
| 132 static const char *error_fread(FILE *fp) { |
| 133 const char *retval = "beats me why"; |
| 134 if (feof(fp)) |
| 135 retval = "EOF"; |
| 136 else if (ferror(fp)) |
| 137 retval = strerror(errno); |
| 138 clearerr(fp); |
| 139 return retval; |
| 140 } |
131 | 141 |
132 /* Return the smallest integral multiple of [alignment] that is equal | 142 /* Return the smallest integral multiple of [alignment] that is equal |
133 * to or greater than [val]. Used to determine the number of | 143 * to or greater than [val]. Used to determine the number of |
134 * pages/sectors/blocks/whatever needed to contain [val] | 144 * pages/sectors/blocks/whatever needed to contain [val] |
135 * items/bytes/etc. */ | 145 * items/bytes/etc. */ |
136 static uint64_t roundup(uint64_t val, uint64_t alignment) { | 146 static uint64_t roundup(uint64_t val, uint64_t alignment) { |
137 uint64_t rem = val % alignment; | 147 uint64_t rem = val % alignment; |
138 if ( rem ) | 148 if ( rem ) |
139 return val + (alignment - rem); | 149 return val + (alignment - rem); |
140 return val; | 150 return val; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 uint64_t now = 0; | 388 uint64_t now = 0; |
379 uint8_t* buf = NULL; | 389 uint8_t* buf = NULL; |
380 int ret_error = 1; | 390 int ret_error = 1; |
381 | 391 |
382 if (!filename) { | 392 if (!filename) { |
383 error("Must specify prepacked blob to read\n"); | 393 error("Must specify prepacked blob to read\n"); |
384 return 0; | 394 return 0; |
385 } | 395 } |
386 | 396 |
387 if (0 != stat(filename, &statbuf)) { | 397 if (0 != stat(filename, &statbuf)) { |
388 error("unable to stat %s: %s\n", filename, strerror(errno)); | 398 error("Unable to stat %s: %s\n", filename, strerror(errno)); |
389 return 0; | 399 return 0; |
390 } | 400 } |
391 | 401 |
392 Debug("%s size is 0x%" PRIx64 "\n", filename, statbuf.st_size); | 402 Debug("%s size is 0x%" PRIx64 "\n", filename, statbuf.st_size); |
393 if (statbuf.st_size < DEFAULT_PADDING) { | 403 if (statbuf.st_size < DEFAULT_PADDING) { |
394 error("%s is too small to be a valid kernel blob\n"); | 404 error("%s is too small to be a valid kernel blob\n"); |
395 return 0; | 405 return 0; |
396 } | 406 } |
397 | 407 |
398 Debug("Reading %s\n", filename); | 408 Debug("Reading %s\n", filename); |
399 fp = fopen(filename, "rb"); | 409 fp = fopen(filename, "rb"); |
400 if (!fp) { | 410 if (!fp) { |
401 error("Unable to open file %s: %s\n", filename, strerror(errno)); | 411 error("Unable to open file %s: %s\n", filename, strerror(errno)); |
402 return 0; | 412 return 0; |
403 } | 413 } |
404 | 414 |
405 buf = Malloc(DEFAULT_PADDING); | 415 buf = Malloc(DEFAULT_PADDING); |
406 if (!buf) { | 416 if (!buf) { |
407 error("Unable to allocate padding\n"); | 417 error("Unable to allocate padding\n"); |
408 goto unwind_oldblob; | 418 goto unwind_oldblob; |
409 } | 419 } |
410 | 420 |
411 if (1 != fread(buf, DEFAULT_PADDING, 1, fp)) { | 421 if (1 != fread(buf, DEFAULT_PADDING, 1, fp)) { |
412 error("Unable to read header from %s: %s\n", filename, strerror(errno)); | 422 error("Unable to read header from %s: %s\n", filename, error_fread(fp)); |
413 goto unwind_oldblob; | 423 goto unwind_oldblob; |
414 } | 424 } |
415 | 425 |
416 /* Skip the key block */ | 426 /* Skip the key block */ |
417 key_block = (VbKeyBlockHeader*)buf; | 427 key_block = (VbKeyBlockHeader*)buf; |
418 Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size); | 428 Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size); |
419 now += key_block->key_block_size; | 429 now += key_block->key_block_size; |
420 if (now > statbuf.st_size) { | 430 if (now > statbuf.st_size) { |
421 error("key_block_size advances past the end of the blob\n"); | 431 error("key_block_size advances past the end of the blob\n"); |
422 goto unwind_oldblob; | 432 goto unwind_oldblob; |
(...skipping 30 matching lines...) Expand all Loading... |
453 bp->kernel_version = preamble->kernel_version; | 463 bp->kernel_version = preamble->kernel_version; |
454 bp->bootloader_address = preamble->bootloader_address; | 464 bp->bootloader_address = preamble->bootloader_address; |
455 bp->bootloader_size = preamble->bootloader_size; | 465 bp->bootloader_size = preamble->bootloader_size; |
456 bp->blob_size = preamble->body_signature.data_size; | 466 bp->blob_size = preamble->body_signature.data_size; |
457 | 467 |
458 Debug(" kernel_version = %d\n", bp->kernel_version); | 468 Debug(" kernel_version = %d\n", bp->kernel_version); |
459 Debug(" bootloader_address = 0x%" PRIx64 "\n", bp->bootloader_address); | 469 Debug(" bootloader_address = 0x%" PRIx64 "\n", bp->bootloader_address); |
460 Debug(" bootloader_size = 0x%" PRIx64 "\n", bp->bootloader_size); | 470 Debug(" bootloader_size = 0x%" PRIx64 "\n", bp->bootloader_size); |
461 Debug(" blob_size = 0x%" PRIx64 "\n", bp->blob_size); | 471 Debug(" blob_size = 0x%" PRIx64 "\n", bp->blob_size); |
462 | 472 |
| 473 if (!bp->blob_size) { |
| 474 error("No kernel blob found\n"); |
| 475 goto unwind_oldblob; |
| 476 } |
| 477 |
463 bp->blob = (uint8_t *)Malloc(bp->blob_size); | 478 bp->blob = (uint8_t *)Malloc(bp->blob_size); |
464 if (!bp->blob) { | 479 if (!bp->blob) { |
465 error("Couldn't allocate 0x%" PRIx64 " bytes for blob_t.\n", bp->blob_size); | 480 error("Couldn't allocate 0x%" PRIx64 " bytes for blob_t.\n", bp->blob_size); |
466 goto unwind_oldblob; | 481 goto unwind_oldblob; |
467 } | 482 } |
468 | 483 |
469 /* read it in */ | 484 /* read it in */ |
470 if (1 != fread(bp->blob, bp->blob_size, 1, fp)) { | 485 if (1 != fread(bp->blob, bp->blob_size, 1, fp)) { |
471 error("Unable to read kernel blob from %s: %s\n", filename, strerror(errno))
; | 486 error("Unable to read kernel blob from %s: %s\n", filename, error_fread(fp))
; |
472 goto unwind_oldblob; | 487 goto unwind_oldblob; |
473 } | 488 } |
474 | 489 |
475 ret_error = 0; | 490 ret_error = 0; |
476 | 491 |
477 /* done */ | 492 /* done */ |
478 unwind_oldblob: | 493 unwind_oldblob: |
479 fclose(fp); | 494 fclose(fp); |
480 if (ret_error) { | 495 if (ret_error) { |
481 if (bp) { | 496 if (bp) { |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 | 884 |
870 case OPT_MODE_VERIFY: | 885 case OPT_MODE_VERIFY: |
871 return Verify(filename, signpubkey, verbose); | 886 return Verify(filename, signpubkey, verbose); |
872 | 887 |
873 default: | 888 default: |
874 fprintf(stderr, | 889 fprintf(stderr, |
875 "You must specify a mode: --pack, --repack or --verify\n"); | 890 "You must specify a mode: --pack, --repack or --verify\n"); |
876 return PrintHelp(progname); | 891 return PrintHelp(progname); |
877 } | 892 } |
878 } | 893 } |
OLD | NEW |