summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--futility/cmd_gscvd.c57
-rw-r--r--futility/cmd_load_fmap.c26
-rw-r--r--futility/cmd_show.c135
-rw-r--r--futility/cmd_sign.c145
-rw-r--r--futility/cmd_validate_rec_mrc.c26
-rw-r--r--futility/file_type.c63
-rw-r--r--futility/file_type.h21
-rw-r--r--futility/file_type_bios.c49
-rw-r--r--futility/file_type_rwsig.c72
-rw-r--r--futility/file_type_usbpd1.c42
-rw-r--r--futility/futility.h25
-rw-r--r--futility/futility_options.h3
-rw-r--r--futility/misc.c75
-rw-r--r--futility/vb2_helper.c52
14 files changed, 469 insertions, 322 deletions
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c
index e8b2fae1..d6187c9f 100644
--- a/futility/cmd_gscvd.c
+++ b/futility/cmd_gscvd.c
@@ -143,35 +143,22 @@ struct gscvd_ro_ranges {
static int load_ap_firmware(const char *file_name, struct file_buf *file,
int mode)
{
- int fd;
- int rv;
+ if (futil_open_and_map_file(file_name, &file->fd, mode, &file->data,
+ &file->len))
+ return 1;
- fd = open(file_name, mode);
- if (fd < 0) {
- ERROR("Can't open %s: %s\n", file_name,
- strerror(errno));
+ if (!fmap_find_by_name(file->data, file->len, NULL, "RO_GSCVD",
+ &file->ro_gscvd)) {
+ ERROR("Could not find RO_GSCVD in the FMAP\n");
+ futil_unmap_and_close_file(file->fd, mode, file->data,
+ file->len);
+ file->fd = -1;
+ file->data = NULL;
+ file->len = 0;
return 1;
}
- file->fd = fd;
- do {
- rv = 1;
-
- if (futil_map_file(fd, mode == O_RDWR ? MAP_RW : MAP_RO,
- &file->data, &file->len)) {
- file->data = NULL;
- break;
- }
-
- if (!fmap_find_by_name(file->data, file->len, NULL, "RO_GSCVD",
- &file->ro_gscvd)) {
- ERROR("Could not find RO_GSCVD in the FMAP\n");
- break;
- }
- rv = 0;
- } while (false);
-
- return rv;
+ return 0;
}
/**
@@ -809,7 +796,7 @@ static int validate_gscvd(int argc, char *argv[])
rv = -1; /* Speculative, will be cleared on success. */
- if (load_ap_firmware(file_name, &ap_firmware_file, O_RDONLY))
+ if (load_ap_firmware(file_name, &ap_firmware_file, FILE_RO))
break;
/* Copy ranges from gscvd to local structure. */
@@ -857,6 +844,11 @@ static int validate_gscvd(int argc, char *argv[])
rv = 0;
} while (false);
+ if (ap_firmware_file.fd != -1)
+ futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RO,
+ ap_firmware_file.data,
+ ap_firmware_file.len);
+
return rv;
}
@@ -1014,7 +1006,7 @@ static int do_gscvd(int argc, char *argv[])
if (validate_privk(kblock, plat_privk))
break;
- if (load_ap_firmware(work_file, &ap_firmware_file, O_RDWR))
+ if (load_ap_firmware(work_file, &ap_firmware_file, FILE_RW))
break;
if (verify_ranges(&ranges, &ap_firmware_file))
@@ -1038,15 +1030,10 @@ static int do_gscvd(int argc, char *argv[])
free(kblock);
vb2_private_key_free(plat_privk);
- /* Now flush the file. */
- if (ap_firmware_file.data) {
- rv |= futil_unmap_file(ap_firmware_file.fd, true,
- ap_firmware_file.data,
- ap_firmware_file.len);
- }
-
if (ap_firmware_file.fd != -1)
- close(ap_firmware_file.fd);
+ futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RW,
+ ap_firmware_file.data,
+ ap_firmware_file.len);
return rv;
}
diff --git a/futility/cmd_load_fmap.c b/futility/cmd_load_fmap.c
index 818fda85..4ab194e1 100644
--- a/futility/cmd_load_fmap.c
+++ b/futility/cmd_load_fmap.c
@@ -149,22 +149,16 @@ static int do_load_fmap(int argc, char *argv[])
else
outfile = infile;
- fd = open(outfile, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "Can't open %s: %s\n",
- outfile, strerror(errno));
- return 1;
- }
+ errorcnt |= futil_open_and_map_file(outfile, &fd, FILE_RW, &buf, &len);
- errorcnt |= futil_map_file(fd, MAP_RW, &buf, &len);
if (errorcnt)
- goto done_file;
+ goto done;
fmap = fmap_find(buf, len);
if (!fmap) {
fprintf(stderr, "Can't find an FMAP in %s\n", infile);
errorcnt++;
- goto done_map;
+ goto done;
}
for (i = optind; i < argc; i++) {
@@ -190,20 +184,10 @@ static int do_load_fmap(int argc, char *argv[])
}
}
-done_map:
- errorcnt |= futil_unmap_file(fd, 1, buf, len);
-
-done_file:
-
- if (0 != close(fd)) {
- fprintf(stderr, "Error closing %s: %s\n",
- outfile, strerror(errno));
- errorcnt++;
- }
-
+done:
+ errorcnt |= futil_unmap_and_close_file(fd, FILE_RW, buf, len);
return !!errorcnt;
}
DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap, VBOOT_VERSION_ALL,
"Replace the contents of specified FMAP areas");
-
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index 08974e4c..9816106a 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -86,31 +86,49 @@ static void show_keyblock(struct vb2_keyblock *keyblock, const char *name,
packed_key_sha1_string(data_key));
}
-int ft_show_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_pubkey(const char *name, void *data)
{
- struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf;
+ int fd = -1;
+ struct vb2_packed_key *pubkey;
+ uint32_t len;
+ int rv = 0;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&pubkey,
+ &len))
+ return 1;
if (vb2_packed_key_looks_ok(pubkey, len)) {
printf("%s looks bogus\n", name);
- return 1;
+ rv = 1;
+ goto done;
}
printf("Public Key file: %s\n", name);
show_pubkey(pubkey, " ");
- return 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pubkey, len);
+ return rv;
}
-int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_privkey(const char *name, void *data)
{
- struct vb2_packed_private_key *pkey =
- (struct vb2_packed_private_key *)buf;
+ int fd = -1;
+ int rv = 0;
+ struct vb2_packed_private_key *pkey = NULL;
+ uint32_t len;
struct vb2_private_key key;
- const unsigned char *start = pkey->key_data;
+ const unsigned char *start;
+ if (futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&pkey,
+ &len))
+ return 1;
+
+ start = pkey->key_data;
if (len <= sizeof(*pkey)) {
printf("%s looks bogus\n", name);
- return 1;
+ rv = 1;
+ goto done;
}
len -= sizeof(*pkey);
key.rsa_private_key = d2i_RSAPrivateKey(NULL, &start, len);
@@ -122,20 +140,30 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data)
printf(" Key sha1sum: %s\n",
private_key_sha1_string(&key));
- return 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pkey, len);
+ return rv;
}
-int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_keyblock(const char *name, void *data)
{
- struct vb2_keyblock *block = (struct vb2_keyblock *)buf;
+ struct vb2_keyblock *block;
struct vb2_public_key *sign_key = show_option.k;
int good_sig = 0;
int retval = 0;
+ int fd = -1;
+ uint32_t len;
+
+ retval = futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&block,
+ &len);
+ if (retval)
+ return 1;
/* Check the hash only first */
if (0 != vb2_verify_keyblock_hash(block, len, &wb)) {
printf("%s is invalid\n", name);
- return 1;
+ retval = 1;
+ goto done;
}
/* Check the signature if we have one */
@@ -148,11 +176,13 @@ int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data)
show_keyblock(block, name, !!sign_key, good_sig);
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)block, len);
return retval;
}
-int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
+ void *data)
{
struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
struct bios_state_s *state = (struct bios_state_s *)data;
@@ -282,17 +312,40 @@ done:
return retval;
}
-int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int ft_show_fw_preamble(const char *name, void *data)
{
- struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
+ int rv = 0;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
+
+ rv = show_fw_preamble_buf(name, buf, len, data);
+
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
+}
+
+int ft_show_kernel_preamble(const char *name, void *data)
+{
+ struct vb2_keyblock *keyblock;
struct vb2_public_key *sign_key = show_option.k;
- int retval = 0;
+ int retval = 1;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
+
+ keyblock = (struct vb2_keyblock *)buf;
/* Check the hash... */
if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
printf("%s keyblock component is invalid\n", name);
- return 1;
+ goto done;
}
/* If we have a key, check the signature too */
@@ -304,13 +357,10 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
printf("Kernel partition: %s\n", name);
show_keyblock(keyblock, NULL, !!sign_key, good_sig);
- if (show_option.strict && (!sign_key || !good_sig))
- retval = 1;
-
struct vb2_public_key data_key;
if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
fprintf(stderr, "Error parsing data key in %s\n", name);
- return 1;
+ goto done;
}
uint32_t more = keyblock->keyblock_size;
@@ -320,7 +370,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
if (VB2_SUCCESS != vb2_verify_kernel_preamble(pre2, len - more,
&data_key, &wb)) {
printf("%s is invalid\n", name);
- return 1;
+ goto done;
}
printf("Kernel Preamble:\n");
@@ -367,20 +417,24 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
if (!kernel_blob) {
/* TODO: Is this always a failure? The preamble is okay. */
fprintf(stderr, "No kernel blob available to verify.\n");
- return 1;
+ goto done;
}
if (VB2_SUCCESS !=
vb2_verify_data(kernel_blob, kernel_size, &pre2->body_signature,
&data_key, &wb)) {
fprintf(stderr, "Error verifying kernel body.\n");
- return 1;
+ goto done;
}
printf("Body verification succeeded.\n");
printf("Config:\n%s\n", kernel_blob + kernel_cmd_line_offset(pre2));
+ if (!show_option.strict || (sign_key && good_sig))
+ retval = 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
return retval;
}
@@ -476,9 +530,8 @@ static int do_show(int argc, char *argv[])
uint8_t *pubkbuf = NULL;
struct vb2_public_key pubk2;
char *infile = 0;
- int ifd, i;
+ int i;
int errorcnt = 0;
- uint8_t *buf;
uint32_t len;
char *e = 0;
int type_override = 0;
@@ -585,34 +638,14 @@ static int do_show(int argc, char *argv[])
for (i = optind; i < argc; i++) {
infile = argv[i];
- ifd = open(infile, O_RDONLY);
- if (ifd < 0) {
- errorcnt++;
- fprintf(stderr, "Can't open %s: %s\n",
- infile, strerror(errno));
- continue;
- }
-
- if (0 != futil_map_file(ifd, MAP_RO, &buf, &len)) {
- errorcnt++;
- goto boo;
- }
/* Allow the user to override the type */
if (type_override)
type = show_option.type;
else
- type = futil_file_type_buf(buf, len);
+ futil_file_type(infile, &type);
- errorcnt += futil_file_type_show(type, infile, buf, len);
-
- errorcnt += futil_unmap_file(ifd, MAP_RO, buf, len);
-boo:
- if (close(ifd)) {
- errorcnt++;
- fprintf(stderr, "Error when closing %s: %s\n",
- infile, strerror(errno));
- }
+ errorcnt += futil_file_type_show(type, infile);
}
done:
diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c
index a08238eb..59999977 100644
--- a/futility/cmd_sign.c
+++ b/futility/cmd_sign.c
@@ -55,14 +55,21 @@ static int no_opt_if(int expr, const char *optname)
}
/* This wraps/signs a public key, producing a keyblock. */
-int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_sign_pubkey(const char *name, void *data)
{
- struct vb2_packed_key *data_key = (struct vb2_packed_key *)buf;
+ struct vb2_packed_key *data_key;
+ uint32_t data_len;
struct vb2_keyblock *block;
+ int rv = 1;
+ int fd = -1;
- if (vb2_packed_key_looks_ok(data_key, len)) {
- fprintf(stderr, "Public key looks bad.\n");
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ (uint8_t **)&data_key, &data_len))
return 1;
+
+ if (vb2_packed_key_looks_ok(data_key, data_len)) {
+ fprintf(stderr, "Public key looks bad.\n");
+ goto done;
}
if (sign_option.pem_signpriv) {
@@ -82,7 +89,7 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
fprintf(stderr,
"Unable to read PEM signing key: %s\n",
strerror(errno));
- return 1;
+ goto done;
}
block = vb2_create_keyblock(data_key,
sign_option.signprivate,
@@ -95,20 +102,24 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
}
/* Write it out */
- return WriteSomeParts(sign_option.outfile,
- block, block->keyblock_size,
- NULL, 0);
+ rv = WriteSomeParts(sign_option.outfile, block, block->keyblock_size,
+ NULL, 0);
+done:
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option),
+ (uint8_t *)data_key, data_len);
+ return rv;
}
-int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int ft_sign_raw_kernel(const char *name, void *data)
{
- uint8_t *vmlinuz_data, *kblob_data, *vblock_data;
+ uint8_t *vmlinuz_data = NULL, *kblob_data = NULL, *vblock_data = NULL;
uint32_t vmlinuz_size, kblob_size, vblock_size;
- int rv;
+ int rv = 1;
+ int fd = -1;
- vmlinuz_data = buf;
- vmlinuz_size = len;
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &vmlinuz_data, &vmlinuz_size))
+ return 1;
kblob_data = CreateKernelBlob(
vmlinuz_data, vmlinuz_size,
@@ -118,7 +129,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
&kblob_size);
if (!kblob_data) {
fprintf(stderr, "Unable to create kernel blob\n");
- return 1;
+ goto done;
}
VB2_DEBUG("kblob_size = %#x\n", kblob_size);
@@ -131,8 +142,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
sign_option.flags, &vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
- free(kblob_data);
- return 1;
+ goto done;
}
VB2_DEBUG("vblock_size = %#x\n", vblock_size);
@@ -150,22 +160,26 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
vblock_data, vblock_size,
kblob_data, kblob_size);
+done:
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option),
+ vmlinuz_data, vmlinuz_size);
free(vblock_data);
free(kblob_data);
return rv;
}
-int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int ft_sign_kern_preamble(const char *name, void *data)
{
- uint8_t *kpart_data, *kblob_data, *vblock_data;
+ uint8_t *kpart_data = NULL, *kblob_data = NULL, *vblock_data = NULL;
uint32_t kpart_size, kblob_size, vblock_size;
struct vb2_keyblock *keyblock = NULL;
struct vb2_kernel_preamble *preamble = NULL;
- int rv = 0;
+ int rv = 1;
+ int fd = -1;
- kpart_data = buf;
- kpart_size = len;
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &kpart_data, &kpart_size))
+ return 1;
/* Note: This just sets some static pointers. It doesn't malloc. */
kblob_data = unpack_kernel_partition(kpart_data, kpart_size,
@@ -174,7 +188,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
if (!kblob_data) {
fprintf(stderr, "Unable to unpack kernel partition\n");
- return 1;
+ goto done;
}
/*
@@ -192,7 +206,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
sign_option.config_data,
sign_option.config_size)) {
fprintf(stderr, "Unable to update config\n");
- return 1;
+ goto done;
}
/* Preserve the version unless a new one is given */
@@ -219,7 +233,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
&vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
- return 1;
+ goto done;
}
VB2_DEBUG("vblock_size = %#x\n", vblock_size);
@@ -238,24 +252,33 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
* all our modifications to the buffer will get flushed to
* disk when we close it. */
memcpy(kpart_data, vblock_data, vblock_size);
+ rv = 0;
}
-
+done:
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), kpart_data,
+ kpart_size);
free(vblock_data);
return rv;
}
-int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int ft_sign_raw_firmware(const char *name, void *data)
{
- struct vb2_signature *body_sig;
- struct vb2_fw_preamble *preamble;
- int rv;
+ struct vb2_signature *body_sig = NULL;
+ struct vb2_fw_preamble *preamble = NULL;
+ uint8_t *buf;
+ uint32_t len;
+ int rv = 1;
+ int fd = -1;
+
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &buf, &len))
+ return 1;
body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate);
if (!body_sig) {
fprintf(stderr, "Error calculating body signature\n");
- return 1;
+ goto done;
}
preamble = vb2_create_fw_preamble(
@@ -267,7 +290,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
if (!preamble) {
fprintf(stderr, "Error creating firmware preamble.\n");
free(body_sig);
- return 1;
+ goto done;
}
rv = WriteSomeParts(sign_option.outfile,
@@ -275,6 +298,8 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
sign_option.keyblock->keyblock_size,
preamble, preamble->preamble_size);
+done:
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len);
free(preamble);
free(body_sig);
@@ -648,12 +673,8 @@ static int do_sign(int argc, char *argv[])
{
char *infile = 0;
int i;
- int ifd = -1;
int errorcnt = 0;
- uint8_t *buf;
- uint32_t buf_len;
char *e = 0;
- int mapping;
int helpind = 0;
int longindex;
@@ -1009,56 +1030,18 @@ static int do_sign(int argc, char *argv[])
if (errorcnt)
goto done;
- if (sign_option.create_new_outfile) {
- /* The input is read-only, the output is write-only. */
- mapping = MAP_RO;
- VB2_DEBUG("open RO %s\n", infile);
- ifd = open(infile, O_RDONLY);
- if (ifd < 0) {
- errorcnt++;
- fprintf(stderr, "Can't open %s for reading: %s\n",
- infile, strerror(errno));
- goto done;
- }
- } else {
+ if (!sign_option.create_new_outfile) {
/* We'll read-modify-write the output file */
- mapping = MAP_RW;
if (sign_option.inout_file_count > 1)
futil_copy_file_or_die(infile, sign_option.outfile);
- VB2_DEBUG("open RW %s\n", sign_option.outfile);
infile = sign_option.outfile;
- ifd = open(sign_option.outfile, O_RDWR);
- if (ifd < 0) {
- errorcnt++;
- fprintf(stderr, "Can't open %s for writing: %s\n",
- sign_option.outfile, strerror(errno));
- goto done;
- }
- }
-
- if (0 != futil_map_file(ifd, mapping, &buf, &buf_len)) {
- errorcnt++;
- goto done;
}
- errorcnt += futil_file_type_sign(sign_option.type, infile,
- buf, buf_len);
-
- errorcnt += futil_unmap_file(ifd, mapping, buf, buf_len);
-
+ errorcnt += futil_file_type_sign(sign_option.type, infile);
done:
- if (ifd >= 0 && close(ifd)) {
- errorcnt++;
- fprintf(stderr, "Error when closing ifd: %s\n",
- strerror(errno));
- }
-
- if (sign_option.signprivate)
- free(sign_option.signprivate);
- if (sign_option.keyblock)
- free(sign_option.keyblock);
- if (sign_option.kernel_subkey)
- free(sign_option.kernel_subkey);
+ free(sign_option.signprivate);
+ free(sign_option.keyblock);
+ free(sign_option.kernel_subkey);
if (sign_option.prikey)
vb2_private_key_free(sign_option.prikey);
diff --git a/futility/cmd_validate_rec_mrc.c b/futility/cmd_validate_rec_mrc.c
index 1d35bed4..7ba59317 100644
--- a/futility/cmd_validate_rec_mrc.c
+++ b/futility/cmd_validate_rec_mrc.c
@@ -222,31 +222,21 @@ static int do_validate_rec_mrc(int argc, char *argv[])
infile = argv[optind++];
- fd = open(infile, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Cannot open %s:%s\n", infile, strerror(errno));
+ if (futil_open_and_map_file(infile, &fd, FILE_RO, &buff, &file_size) !=
+ FILE_ERR_NONE)
return 1;
- }
-
- if (futil_map_file(fd, MAP_RO, &buff, &file_size) != FILE_ERR_NONE) {
- fprintf(stderr, "Cannot map file %s\n", infile);
- close(fd);
- return 1;
- }
if (offset > file_size) {
fprintf(stderr, "File size(%#x) smaller than offset(%#x)\n",
file_size, offset);
- futil_unmap_file(fd, MAP_RO, buff, file_size);
- close(fd);
+ futil_unmap_and_close_file(fd, FILE_RO, buff, file_size);
return 1;
}
if (get_mrc_data_slot((uint16_t *)(buff + offset), &data_offset,
&data_size)) {
fprintf(stderr, "Metadata block error\n");
- futil_unmap_file(fd, MAP_RO, buff, file_size);
- close(fd);
+ futil_unmap_and_close_file(fd, FILE_RO, buff, file_size);
return 1;
}
offset += data_offset;
@@ -259,12 +249,10 @@ static int do_validate_rec_mrc(int argc, char *argv[])
"offset=%#x, file size=%#x, data_size=%#x\n",
offset, file_size, data_size);
- if (futil_unmap_file(fd, MAP_RO, buff, file_size) != FILE_ERR_NONE) {
- fprintf(stderr, "Failed to unmap file %s\n", infile);
- ret = 1;
- }
+ if (futil_unmap_and_close_file(fd, FILE_RO, buff, file_size) !=
+ FILE_ERR_NONE)
+ return 1;
- close(fd);
return ret;
}
diff --git a/futility/file_type.c b/futility/file_type.c
index b55d13f1..29c4667e 100644
--- a/futility/file_type.c
+++ b/futility/file_type.c
@@ -24,8 +24,8 @@ struct futil_file_type_s {
const char *desc;
/* Functions to identify, display, and sign this type of file. */
enum futil_file_type (*recognize)(uint8_t *buf, uint32_t len);
- int (*show)(const char *name, uint8_t *buf, uint32_t len, void *data);
- int (*sign)(const char *name, uint8_t *buf, uint32_t len, void *data);
+ int (*show)(const char *name, void *data);
+ int (*sign)(const char *name, void *data);
};
/* Populate a list of file types and operator functions. */
@@ -99,42 +99,29 @@ enum futil_file_type futil_file_type_buf(uint8_t *buf, uint32_t len)
enum futil_file_err futil_file_type(const char *filename,
enum futil_file_type *type)
{
- int ifd;
- uint8_t *buf;
- uint32_t buf_len;
+ int ifd = -1;
+ uint8_t *buf = NULL;
+ uint32_t buf_len = 0;
struct stat sb;
enum futil_file_err err = FILE_ERR_NONE;
*type = FILE_TYPE_UNKNOWN;
- ifd = open(filename, O_RDONLY);
- if (ifd < 0) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return FILE_ERR_OPEN;
- }
+ err = futil_open_file(filename, &ifd, FILE_RO);
+ if (err != FILE_ERR_NONE)
+ goto done;
if (0 != fstat(ifd, &sb)) {
- fprintf(stderr, "Can't stat input file: %s\n",
- strerror(errno));
- close(ifd);
- return FILE_ERR_STAT;
+ fprintf(stderr, "Can't stat input file: %s\n", strerror(errno));
+ err = FILE_ERR_STAT;
+ goto done;
}
if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) {
- err = futil_map_file(ifd, MAP_RO, &buf, &buf_len);
- if (err) {
- close(ifd);
- return err;
- }
-
+ err = futil_map_file(ifd, FILE_RO, &buf, &buf_len);
+ if (err)
+ goto done;
*type = futil_file_type_buf(buf, buf_len);
-
- err = futil_unmap_file(ifd, MAP_RO, buf, buf_len);
- if (err) {
- close(ifd);
- return err;
- }
} else if (S_ISDIR(sb.st_mode)) {
err = FILE_ERR_DIR;
} else if (S_ISCHR(sb.st_mode)) {
@@ -144,37 +131,27 @@ enum futil_file_err futil_file_type(const char *filename,
} else if (S_ISSOCK(sb.st_mode)) {
err = FILE_ERR_SOCK;
}
-
- if (close(ifd)) {
- fprintf(stderr, "Error when closing %s: %s\n",
- filename, strerror(errno));
- return FILE_ERR_CLOSE;
- }
-
+done:
+ futil_unmap_and_close_file(ifd, FILE_RO, buf, buf_len);
return err;
}
-int futil_file_type_show(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len)
+int futil_file_type_show(enum futil_file_type type, const char *filename)
{
if (futil_file_types[type].show)
- return futil_file_types[type].show(filename, buf, len, 0);
+ return futil_file_types[type].show(filename, 0);
fprintf(stderr, "Don't know how to show %s (type %s)\n",
filename, futil_file_type_name(type));
return 1;
}
-int futil_file_type_sign(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len)
+int futil_file_type_sign(enum futil_file_type type, const char *filename)
{
if (futil_file_types[type].sign)
- return futil_file_types[type].sign(filename, buf, len, 0);
+ return futil_file_types[type].sign(filename, 0);
fprintf(stderr, "Don't know how to sign %s (type %s)\n",
filename, futil_file_type_name(type));
return 1;
}
-
diff --git a/futility/file_type.h b/futility/file_type.h
index e1efe760..5a074b3e 100644
--- a/futility/file_type.h
+++ b/futility/file_type.h
@@ -40,22 +40,18 @@ enum futil_file_err futil_file_type(const char *filename,
enum futil_file_type *type);
/*
- * Call the show() method on a buffer containing a specific file type.
+ * Call the show() method on a file containing a specific file type.
* Returns zero on success. It's up to the caller to ensure that only valid
* file types are invoked.
*/
-int futil_file_type_show(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len);
+int futil_file_type_show(enum futil_file_type type, const char *filename);
/*
- * Call the sign() method on a buffer containing a specific file type.
+ * Call the sign() method on a file with specific file type.
* Returns zero on success. It's up to the caller to ensure that only valid
* file types are invoked.
*/
-int futil_file_type_sign(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len);
+int futil_file_type_sign(enum futil_file_type type, const char *filename);
/*
* Declare the file_type functions. Certain functions are reused for more than
@@ -66,14 +62,21 @@ int futil_file_type_sign(enum futil_file_type type,
#define R_(FOO) \
enum futil_file_type FOO(uint8_t *buf, uint32_t len);
#define S_(FOO) \
- int FOO(const char *name, uint8_t *buf, uint32_t len, void *data);
+ int FOO(const char *name, void *data);
#define NONE
#define FILE_TYPE(A, B, C, D, E, F) D E F
#include "file_type.inc"
#undef FILE_TYPE
#undef NONE
+#undef SG_
#undef S_
#undef R_
#pragma GCC diagnostic pop
+/* Declared for use inside other show functions. */
+int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
+ void *data);
+int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len,
+ void *data);
+
#endif /* VBOOT_REFERENCE_FILE_TYPE_H_ */
diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c
index 6427201b..17efddec 100644
--- a/futility/file_type_bios.c
+++ b/futility/file_type_bios.c
@@ -40,7 +40,8 @@ static void fmap_limit_area(FmapAreaHeader *ah, uint32_t len)
/** Show functions **/
-int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
+static int show_gbb_buf(const char *name, uint8_t *buf, uint32_t len,
+ void *data)
{
struct vb2_gbb_header *gbb = (struct vb2_gbb_header *)buf;
struct bios_state_s *state = (struct bios_state_s *)data;
@@ -75,7 +76,7 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
if (retval) {
printf("GBB header is invalid, ignoring content\n");
- return 1;
+ return retval;
}
printf("GBB content:\n");
@@ -125,6 +126,23 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
return retval;
}
+int ft_show_gbb(const char *name, void *data)
+{
+ int retval = 0;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+
+ retval = futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len);
+ if (retval)
+ return 1;
+
+ retval = show_gbb_buf(name, buf, len, data);
+
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return retval;
+}
+
/*
* This handles FW_MAIN_A and FW_MAIN_B while processing a BIOS image.
*
@@ -155,16 +173,16 @@ static int fmap_show_fw_main(const char *name, uint8_t *buf, uint32_t len,
/* Functions to call to show the bios components */
static int (*fmap_show_fn[])(const char *name, uint8_t *buf, uint32_t len,
void *data) = {
- ft_show_gbb,
+ show_gbb_buf,
fmap_show_fw_main,
fmap_show_fw_main,
- ft_show_fw_preamble,
- ft_show_fw_preamble,
+ show_fw_preamble_buf,
+ show_fw_preamble_buf,
};
_Static_assert(ARRAY_SIZE(fmap_show_fn) == NUM_BIOS_COMPONENTS,
"Size of fmap_show_fn[] should match NUM_BIOS_COMPONENTS");
-int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_bios(const char *name, void *data)
{
FmapHeader *fmap;
FmapAreaHeader *ah = 0;
@@ -172,6 +190,13 @@ int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
enum bios_component c;
int retval = 0;
struct bios_state_s state;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+
+ retval = futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len);
+ if (retval)
+ return 1;
memset(&state, 0, sizeof(state));
@@ -206,6 +231,7 @@ int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
}
}
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
return retval;
}
@@ -428,7 +454,7 @@ static int (*fmap_sign_fn[])(const char *name, uint8_t *buf, uint32_t len,
_Static_assert(ARRAY_SIZE(fmap_sign_fn) == NUM_BIOS_COMPONENTS,
"Size of fmap_sign_fn[] should match NUM_BIOS_COMPONENTS");
-int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_sign_bios(const char *name, void *data)
{
FmapHeader *fmap;
FmapAreaHeader *ah = 0;
@@ -436,6 +462,14 @@ int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
enum bios_component c;
int retval = 0;
struct bios_state_s state;
+ int fd = -1;
+ uint8_t *buf = NULL;
+ uint32_t len = 0;
+
+ retval = futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &buf, &len);
+ if (retval)
+ return 1;
memset(&state, 0, sizeof(state));
@@ -469,6 +503,7 @@ int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
retval += sign_bios_at_end(&state);
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len);
return retval;
}
diff --git a/futility/file_type_rwsig.c b/futility/file_type_rwsig.c
index a09782ce..b595e250 100644
--- a/futility/file_type_rwsig.c
+++ b/futility/file_type_rwsig.c
@@ -58,7 +58,7 @@ static void show_sig(const char *name, const struct vb21_signature *sig)
sig->data_size);
}
-int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
+int ft_show_rwsig(const char *name, void *nuthin)
{
const struct vb21_signature *sig = 0;
const struct vb21_packed_key *pkey = show_option.pkey;
@@ -71,6 +71,15 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
uint8_t *data;
FmapHeader *fmap;
int i;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+ int rv;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
+
+ rv = 1;
VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len);
@@ -81,7 +90,8 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
show_sig(name, sig);
if (!show_option.fv) {
printf("No data available to verify\n");
- return show_option.strict;
+ rv = show_option.strict;
+ goto done;
}
data = show_option.fv;
data_size = show_option.fv_size;
@@ -99,15 +109,15 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
fmap_find_by_name(buf, len, fmap, "KEY_RO", 0);
if (pkey)
- ft_show_vb21_pubkey(name, (uint8_t *)pkey,
- pkey->c.total_size, NULL);
+ show_vb21_pubkey_buf(name, (uint8_t *)pkey,
+ pkey->c.total_size, NULL);
}
sig = (const struct vb21_signature *)
fmap_find_by_name(buf, len, fmap, "SIG_RW", &fmaparea);
if (!sig) {
VB2_DEBUG("No SIG_RW in FMAP.\n");
- return 1;
+ goto done;
}
sig_size = fmaparea->area_size;
@@ -116,7 +126,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
(uint8_t*)sig - buf, sig_size);
if (VB2_SUCCESS != vb21_verify_signature(sig, sig_size))
- return 1;
+ goto done;
show_sig(name, sig);
data = fmap_find_by_name(buf, len, fmap, "EC_RW", &fmaparea);
@@ -129,7 +139,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
if (!data) {
VB2_DEBUG("No EC_RW in FMAP.\n");
- return 1;
+ goto done;
}
} else {
/* Or maybe this is just the RW portion, that does not
@@ -141,7 +151,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
if (len < sig_size) {
VB2_DEBUG("File is too small\n");
- return 1;
+ goto done;
}
sig = (const struct vb21_signature *)(buf + len - sig_size);
@@ -151,13 +161,14 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
data_size = sig->data_size;
total_data_size = len - sig_size;
} else {
- return 1;
+ goto done;
}
}
if (!pkey) {
printf("No public key available to verify with\n");
- return show_option.strict;
+ rv = show_option.strict;
+ goto done;
}
/* We already did this once, so it should work again */
@@ -165,12 +176,12 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
(const uint8_t *)pkey,
pkey->c.total_size)) {
VB2_DEBUG("Can't unpack pubkey\n");
- return 1;
+ goto done;
}
if (data_size > total_data_size) {
VB2_DEBUG("Invalid signature data_size: bigger than total area size.\n");
- return 1;
+ goto done;
}
/* The sig is destroyed by the verify operation, so make a copy */
@@ -185,7 +196,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
(const struct vb2_public_key *)&key,
&wb)) {
fprintf(stderr, "Signature verification failed\n");
- return 1;
+ goto done;
}
}
@@ -193,33 +204,46 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
for (i = data_size; i < total_data_size; i++) {
if (data[i] != 0xff) {
fprintf(stderr, "Padding verification failed\n");
- return 1;
+ goto done;
}
}
printf("Signature verification succeeded.\n");
- return 0;
+ rv = 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
}
-int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
+int ft_sign_rwsig(const char *name, void *nuthin)
{
struct vb21_signature *tmp_sig = 0;
struct vb2_public_key *pubkey = 0;
struct vb21_packed_key *packedkey = 0;
uint8_t *keyb_data = 0;
uint32_t keyb_size;
- uint8_t* data = buf; /* data to be signed */
- uint32_t r, data_size = len, sig_size = SIGNATURE_RSVD_SIZE;
+ uint8_t *data; /* data to be signed */
+ uint32_t r, data_size, sig_size = SIGNATURE_RSVD_SIZE;
int retval = 1;
FmapHeader *fmap = NULL;
FmapAreaHeader *fmaparea;
struct vb21_signature *old_sig = 0;
+ uint8_t *buf = NULL;
+ uint32_t len;
+ int fd = -1;
+
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &buf, &len))
+ return 1;
+
+ data = buf;
+ data_size = len;
VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len);
/* If we don't have a distinct OUTFILE, look for an existing sig */
if (sign_option.inout_file_count < 2) {
- fmap = fmap_find(buf, len);
+ fmap = fmap_find(data, len);
if (fmap) {
/* This looks like a full image. */
@@ -395,14 +419,12 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
/* Finally */
retval = 0;
done:
- if (tmp_sig)
- free(tmp_sig);
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len);
+ free(tmp_sig);
if (pubkey)
vb2_public_key_free(pubkey);
- if (packedkey)
- free(packedkey);
- if (keyb_data)
- free(keyb_data);
+ free(packedkey);
+ free(keyb_data);
return retval;
}
diff --git a/futility/file_type_usbpd1.c b/futility/file_type_usbpd1.c
index 93791883..a128a996 100644
--- a/futility/file_type_usbpd1.c
+++ b/futility/file_type_usbpd1.c
@@ -78,7 +78,7 @@ static int parse_size_opts(uint32_t len,
return 1;
}
-int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_sign_usbpd1(const char *name, void *data)
{
struct vb2_private_key *key_ptr = 0;
struct vb21_signature *sig_ptr = 0;
@@ -94,6 +94,13 @@ int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
uint32_t ro_offset;
uint32_t rw_offset;
uint32_t r;
+ uint8_t *buf = NULL;
+ uint32_t len;
+ int fd = -1;
+
+ if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option),
+ &buf, &len))
+ return 1;
VB2_DEBUG("name %s len %#.8x (%d)\n", name, len, len);
@@ -237,6 +244,7 @@ int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
/* Finally */
retval = 0;
done:
+ futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len);
if (key_ptr)
vb2_private_key_free(key_ptr);
if (keyb_data)
@@ -425,35 +433,47 @@ static vb2_error_t check_self_consistency(const uint8_t *buf, const char *name,
}
-int ft_show_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_usbpd1(const char *name, void *data)
{
uint32_t ro_size, rw_size, ro_offset, rw_offset;
int s, h;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+ int rv = 1;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len);
/* Get image locations */
if (!parse_size_opts(len, &ro_size, &rw_size, &ro_offset, &rw_offset))
- return 1;
+ goto done;
/* TODO: If we don't have a RO image, ask for a public key
* TODO: If we're given an external public key, use it (and its alg) */
if (!ro_size) {
printf("Can't find the public key\n");
- return 1;
+ goto done;
}
/* TODO: Only loop through the numbers we haven't been given */
- for (s = 0; s < ARRAY_SIZE(sigs); s++)
- for (h = 0; h < ARRAY_SIZE(hashes); h++)
- if (!check_self_consistency(buf, name,
- ro_size, rw_size,
+ for (s = 0; s < ARRAY_SIZE(sigs); s++) {
+ for (h = 0; h < ARRAY_SIZE(hashes); h++) {
+ if (!check_self_consistency(buf, name, ro_size, rw_size,
ro_offset, rw_offset,
- sigs[s], hashes[h]))
- return 0;
+ sigs[s], hashes[h])) {
+ rv = 0;
+ goto done;
+ }
+ }
+ }
printf("This doesn't appear to be a complete usbpd1 image\n");
- return 1;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
}
enum futil_file_type ft_recognize_usbpd1(uint8_t *buf, uint32_t len)
diff --git a/futility/futility.h b/futility/futility.h
index 9d40ba7e..fa4d3de2 100644
--- a/futility/futility.h
+++ b/futility/futility.h
@@ -132,13 +132,26 @@ enum futil_file_err {
FILE_ERR_SOCK,
};
+enum file_mode {
+ FILE_RO,
+ FILE_RW,
+};
+
+enum futil_file_err futil_open_file(const char *infile, int *fd,
+ enum file_mode mode);
+enum futil_file_err futil_close_file(int fd);
+
/* Wrapper for mmap/munmap. Skips stupidly large files. */
-#define MAP_RO 0
-#define MAP_RW 1
-enum futil_file_err futil_map_file(int fd, int writeable,
- uint8_t **buf, uint32_t *len);
-enum futil_file_err futil_unmap_file(int fd, int writeable,
- uint8_t *buf, uint32_t len);
+enum futil_file_err futil_map_file(int fd, enum file_mode mode, uint8_t **buf,
+ uint32_t *len);
+enum futil_file_err futil_unmap_file(int fd, enum file_mode mode, uint8_t *buf,
+ uint32_t len);
+
+enum futil_file_err futil_open_and_map_file(const char *infile, int *fd,
+ enum file_mode mode, uint8_t **buf,
+ uint32_t *len);
+enum futil_file_err futil_unmap_and_close_file(int fd, enum file_mode mode,
+ uint8_t *buf, uint32_t len);
/*
* Parse input string as a hex representation of size len, exit with error if
diff --git a/futility/futility_options.h b/futility/futility_options.h
index a79505c3..9c99bba1 100644
--- a/futility/futility_options.h
+++ b/futility/futility_options.h
@@ -67,4 +67,7 @@ struct sign_option_s {
};
extern struct sign_option_s sign_option;
+#define FILE_MODE_SIGN(sign_options) \
+ (sign_options.create_new_outfile ? FILE_RO : FILE_RW)
+
#endif /* VBOOT_REFERENCE_FUTILITY_OPTIONS_H_ */
diff --git a/futility/misc.c b/futility/misc.c
index 76b8ad1e..4aec13a3 100644
--- a/futility/misc.c
+++ b/futility/misc.c
@@ -5,6 +5,7 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#if !defined(HAVE_MACOS) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
#include <linux/fs.h> /* For BLKGETSIZE64 */
#endif
@@ -258,8 +259,40 @@ void futil_copy_file_or_die(const char *infile, const char *outfile)
exit(1);
}
+enum futil_file_err futil_open_file(const char *infile, int *fd,
+ enum file_mode mode)
+{
+ if (mode == FILE_RW) {
+ VB2_DEBUG("open RW %s\n", infile);
+ *fd = open(infile, O_RDWR);
+ if (*fd < 0) {
+ fprintf(stderr, "Can't open %s for writing: %s\n",
+ infile, strerror(errno));
+ return FILE_ERR_OPEN;
+ }
+ } else {
+ VB2_DEBUG("open RO %s\n", infile);
+ *fd = open(infile, O_RDONLY);
+ if (*fd < 0) {
+ fprintf(stderr, "Can't open %s for reading: %s\n",
+ infile, strerror(errno));
+ return FILE_ERR_OPEN;
+ }
+ }
+ return FILE_ERR_NONE;
+}
+
+enum futil_file_err futil_close_file(int fd)
+{
+ if (fd >= 0 && close(fd)) {
+ fprintf(stderr, "Error when closing ifd: %s\n",
+ strerror(errno));
+ return FILE_ERR_CLOSE;
+ }
+ return FILE_ERR_NONE;
+}
-enum futil_file_err futil_map_file(int fd, int writeable,
+enum futil_file_err futil_map_file(int fd, enum file_mode mode,
uint8_t **buf, uint32_t *len)
{
struct stat sb;
@@ -284,7 +317,7 @@ enum futil_file_err futil_map_file(int fd, int writeable,
}
reasonable_len = (uint32_t)sb.st_size;
- if (writeable)
+ if (mode == FILE_RW)
mmap_ptr = mmap(0, sb.st_size,
PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
else
@@ -293,7 +326,7 @@ enum futil_file_err futil_map_file(int fd, int writeable,
if (mmap_ptr == (void *)-1) {
fprintf(stderr, "Can't mmap %s file: %s\n",
- writeable ? "output" : "input",
+ mode == FILE_RW ? "output" : "input",
strerror(errno));
return FILE_ERR_MMAP;
}
@@ -303,14 +336,14 @@ enum futil_file_err futil_map_file(int fd, int writeable,
return FILE_ERR_NONE;
}
-enum futil_file_err futil_unmap_file(int fd, int writeable,
+enum futil_file_err futil_unmap_file(int fd, enum file_mode mode,
uint8_t *buf, uint32_t len)
{
void *mmap_ptr = buf;
enum futil_file_err err = FILE_ERR_NONE;
- if (writeable &&
- (0 != msync(mmap_ptr, len, MS_SYNC|MS_INVALIDATE))) {
+ if (mode == FILE_RW &&
+ (0 != msync(mmap_ptr, len, MS_SYNC | MS_INVALIDATE))) {
fprintf(stderr, "msync failed: %s\n", strerror(errno));
err = FILE_ERR_MSYNC;
}
@@ -325,6 +358,36 @@ enum futil_file_err futil_unmap_file(int fd, int writeable,
return err;
}
+enum futil_file_err futil_open_and_map_file(const char *infile, int *fd,
+ enum file_mode mode, uint8_t **buf,
+ uint32_t *len)
+{
+ enum futil_file_err rv = futil_open_file(infile, fd, mode);
+ if (rv != FILE_ERR_NONE)
+ return rv;
+
+ rv = futil_map_file(*fd, mode, buf, len);
+ if (rv != FILE_ERR_NONE)
+ futil_close_file(*fd);
+
+ return rv;
+}
+
+enum futil_file_err futil_unmap_and_close_file(int fd, enum file_mode mode,
+ uint8_t *buf, uint32_t len)
+{
+ enum futil_file_err rv = FILE_ERR_NONE;
+
+ if (buf)
+ rv = futil_unmap_file(fd, mode, buf, len);
+ if (rv != FILE_ERR_NONE)
+ return rv;
+
+ if (fd != -1)
+ return futil_close_file(fd);
+ else
+ return FILE_ERR_NONE;
+}
#define DISK_SECTOR_SIZE 512
enum futil_file_type ft_recognize_gpt(uint8_t *buf, uint32_t len)
diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c
index 4d676a68..a8452db6 100644
--- a/futility/vb2_helper.c
+++ b/futility/vb2_helper.c
@@ -60,7 +60,7 @@ static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest)
return 1;
}
-int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len,
+int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len,
void *data)
{
struct vb2_public_key key;
@@ -91,6 +91,22 @@ int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len,
return 0;
}
+int ft_show_vb21_pubkey(const char *name, void *data)
+{
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+ int rv;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
+
+ rv = show_vb21_pubkey_buf(name, buf, len, data);
+
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
+}
+
static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
{
uint8_t *buf;
@@ -106,15 +122,23 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
return 1;
}
-int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len,
- void *data)
+int ft_show_vb21_privkey(const char *name, void *data)
{
struct vb2_private_key *key = 0;
uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+ int rv = 0;
- if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len))
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
return 1;
+ if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len)) {
+ rv = 1;
+ goto done;
+ }
+
printf("Private key file: %s\n", name);
printf(" Vboot API: 2.1\n");
printf(" Desc: \"%s\"\n", key->desc ? key->desc : "");
@@ -132,7 +156,9 @@ int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len,
printf("\n");
}
vb2_private_key_free(key);
- return 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
}
static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len)
@@ -172,7 +198,7 @@ enum futil_file_type ft_recognize_pem(uint8_t *buf, uint32_t len)
return FILE_TYPE_UNKNOWN;
}
-int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
+int ft_show_pem(const char *name, void *data)
{
RSA *rsa_key;
uint8_t *keyb;
@@ -180,6 +206,13 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
uint32_t keyb_len;
int i, bits;
const BIGNUM *rsa_key_n, *rsa_key_d;
+ int fd = -1;
+ uint8_t *buf;
+ uint32_t len;
+ int rv = 0;
+
+ if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
+ return 1;
/* We're called only after ft_recognize_pem, so this should work. */
rsa_key = rsa_from_buffer(buf, len);
@@ -197,7 +230,8 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
if (vb_keyb_from_rsa(rsa_key, &keyb, &keyb_len)) {
printf(" Key sha1sum: <error>");
RSA_free(rsa_key);
- return 1;
+ rv = 1;
+ goto done;
}
printf(" Key sha1sum: ");
@@ -209,5 +243,7 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
free(keyb);
RSA_free(rsa_key);
- return 0;
+done:
+ futil_unmap_and_close_file(fd, FILE_RO, buf, len);
+ return rv;
}