cbfstool: Hide hash printing behind -v and add to parseable output

With the upcoming introduction of CBFS verification, a lot more CBFS
files will have hashes. The current cbfstool default of always printing
hash attributes when they exist will make cbfstool print very messy.
Therefore, hide hash attribute output unless the user passed -v.

It would also be useful to be able to get file attributes like hashes in
machine parseable output. Unfortunately, our machine parseable format
(-k) doesn't really seem designed to be extensible. To avoid breaking
older parsers, this patch adds new attribute output behind -v (which
hopefully no current users pass since it doesn't change anything for -k
at the moment). With this patch cbfstool print -k -v may print an
arbitrary amount of extra tokens behind the predefined ones on a file
line. Tokens always begin with an identifying string (e.g. 'hash'),
followed by extra fields that should be separated by colons. Multiple
tokens are separated by the normal separator character (tab).

cbfstool print -k -v may also print additional information that applies
to the whole CBFS on separate lines. These lines will always begin with
a '[' (which hopefully nobody would use as a CBFS filename character
although we technically have no restrictions at the moment).

Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I9e16cda393fa0bc1d8734d4b699e30e2ae99a36d
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41119
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Julius Werner 2020-04-27 19:31:03 -07:00
parent 7066a1e7b3
commit c4ee28c61d
3 changed files with 41 additions and 14 deletions

View File

@ -1488,6 +1488,9 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
decompressed_size decompressed_size
); );
if (!verbose)
return 0;
struct cbfs_file_attr_hash *attr = NULL; struct cbfs_file_attr_hash *attr = NULL;
while ((attr = cbfs_file_get_next_hash(entry, attr)) != NULL) { while ((attr = cbfs_file_get_next_hash(entry, attr)) != NULL) {
size_t hash_len = vb2_digest_size(attr->hash.algo); size_t hash_len = vb2_digest_size(attr->hash.algo);
@ -1507,9 +1510,6 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
free(hash_str); free(hash_str);
} }
if (!verbose)
return 0;
DEBUG(" cbfs_file=0x%x, offset=0x%x, content_address=0x%x+0x%x\n", DEBUG(" cbfs_file=0x%x, offset=0x%x, content_address=0x%x+0x%x\n",
cbfs_get_entry_addr(image, entry), ntohl(entry->offset), cbfs_get_entry_addr(image, entry), ntohl(entry->offset),
cbfs_get_entry_addr(image, entry) + ntohl(entry->offset), cbfs_get_entry_addr(image, entry) + ntohl(entry->offset),
@ -1572,21 +1572,45 @@ static int cbfs_print_parseable_entry_info(struct cbfs_image *image,
fprintf(fp, "%s%s", type, sep); fprintf(fp, "%s%s", type, sep);
fprintf(fp, "0x%zx%s", metadata_size, sep); fprintf(fp, "0x%zx%s", metadata_size, sep);
fprintf(fp, "0x%zx%s", data_size, sep); fprintf(fp, "0x%zx%s", data_size, sep);
fprintf(fp, "0x%zx\n", metadata_size + data_size); fprintf(fp, "0x%zx", metadata_size + data_size);
if (verbose) {
unsigned int decompressed_size = 0;
unsigned int compression = cbfs_file_get_compression_info(entry,
&decompressed_size);
if (compression != CBFS_COMPRESS_NONE)
fprintf(fp, "%scomp:%s:0x%x", sep, lookup_name_by_type(
types_cbfs_compression, compression, "????"),
decompressed_size);
struct cbfs_file_attr_hash *attr = NULL;
while ((attr = cbfs_file_get_next_hash(entry, attr)) != NULL) {
size_t hash_len = vb2_digest_size(attr->hash.algo);
if (!hash_len)
continue;
char *hash_str = bintohex(attr->hash.raw, hash_len);
int valid = vb2_hash_verify(CBFS_SUBHEADER(entry),
ntohl(entry->len), &attr->hash) == VB2_SUCCESS;
fprintf(fp, "%shash:%s:%s:%s", sep,
vb2_get_hash_algorithm_name(attr->hash.algo),
hash_str, valid ? "valid" : "invalid");
free(hash_str);
}
}
fprintf(fp, "\n");
return 0; return 0;
} }
int cbfs_print_directory(struct cbfs_image *image) void cbfs_print_directory(struct cbfs_image *image)
{ {
if (cbfs_is_legacy_cbfs(image)) if (cbfs_is_legacy_cbfs(image))
cbfs_print_header_info(image); cbfs_print_header_info(image);
printf("%-30s %-10s %-12s Size Comp\n", "Name", "Offset", "Type"); printf("%-30s %-10s %-12s Size Comp\n", "Name", "Offset", "Type");
cbfs_legacy_walk(image, cbfs_print_entry_info, NULL); cbfs_legacy_walk(image, cbfs_print_entry_info, NULL);
return 0;
} }
int cbfs_print_parseable_directory(struct cbfs_image *image) void cbfs_print_parseable_directory(struct cbfs_image *image)
{ {
size_t i; size_t i;
const char *header[] = { const char *header[] = {
@ -1603,7 +1627,6 @@ int cbfs_print_parseable_directory(struct cbfs_image *image)
fprintf(stdout, "%s%s", header[i], sep); fprintf(stdout, "%s%s", header[i], sep);
fprintf(stdout, "%s\n", header[i]); fprintf(stdout, "%s\n", header[i]);
cbfs_legacy_walk(image, cbfs_print_parseable_entry_info, stdout); cbfs_legacy_walk(image, cbfs_print_parseable_entry_info, stdout);
return 0;
} }
int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry, int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,

View File

@ -162,8 +162,8 @@ int cbfs_is_legacy_cbfs(struct cbfs_image *image);
int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry); int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry);
/* Print CBFS component information. */ /* Print CBFS component information. */
int cbfs_print_directory(struct cbfs_image *image); void cbfs_print_directory(struct cbfs_image *image);
int cbfs_print_parseable_directory(struct cbfs_image *image); void cbfs_print_parseable_directory(struct cbfs_image *image);
int cbfs_print_header_info(struct cbfs_image *image); int cbfs_print_header_info(struct cbfs_image *image);
int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry, int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
void *arg); void *arg);

View File

@ -1084,12 +1084,16 @@ static int cbfs_print(void)
if (cbfs_image_from_buffer(&image, param.image_region, if (cbfs_image_from_buffer(&image, param.image_region,
param.headeroffset)) param.headeroffset))
return 1; return 1;
if (param.machine_parseable) if (param.machine_parseable) {
return cbfs_print_parseable_directory(&image); if (verbose)
else { printf("[FMAP REGION]\t%s\n", param.region_name);
cbfs_print_parseable_directory(&image);
} else {
printf("FMAP REGION: %s\n", param.region_name); printf("FMAP REGION: %s\n", param.region_name);
return cbfs_print_directory(&image); cbfs_print_directory(&image);
} }
return 0;
} }
static int cbfs_extract(void) static int cbfs_extract(void)