summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Czapiga <jacz@semihalf.com>2022-03-31 11:42:49 +0200
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-14 08:50:21 +0000
commit8f851be54880fd941f2b49f5fa0419071eb89d81 (patch)
tree29f05605ab97c6fdf291217c769231421d8de983
parente49bfbca21a3aeec31472aac7774c8dec94a4f17 (diff)
downloadvboot-8f851be54880fd941f2b49f5fa0419071eb89d81.tar.gz
futility: Rework file opening and mapping
Adding calls to cbfstool truncate command requires file to be closed and not mapped to work correctly. This patch reworks file opening and mapping to make it simpler. It also moves responsibility from main command runner to command functions to correctly operate on their input/output files. BUG=b:197114807 TEST=sudo FEATURES=test emerge vboot_reference TEST=build and boot while chromeos-bootimage and boot on volteer/voxel platform BRANCH=none Signed-off-by: Jakub Czapiga <jacz@semihalf.com> Change-Id: Iee24fdc43f2a57f54c65f6e55cdd26adf44a0b29 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3575324 Tested-by: Jakub Czapiga <czapiga@google.com> Reviewed-by: Julius Werner <jwerner@chromium.org> Commit-Queue: Julius Werner <jwerner@chromium.org> Auto-Submit: Jakub Czapiga <czapiga@google.com>
-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;
}