diff options
author | Eric Biggers <ebiggers@google.com> | 2019-05-20 17:03:46 -0700 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2019-05-20 17:03:46 -0700 |
commit | e64d479f2975df8e60788264a2d0ab4351b2965f (patch) | |
tree | 195dd07299e5fbfec207f9c1cd29d981cbff9e1e | |
parent | b0ebc3e09cbbd899a0a4c8fa462af7197c06296c (diff) | |
download | fsverity-utils-e64d479f2975df8e60788264a2d0ab4351b2965f.tar.gz |
Remove elide and patch support
These were dropped from the kernel patchset a while ago.
Signed-off-by: Eric Biggers <ebiggers@google.com>
-rw-r--r-- | cmd_setup.c | 38 | ||||
-rw-r--r-- | elide_patch.c | 307 | ||||
-rw-r--r-- | fsverity.c | 1 | ||||
-rw-r--r-- | fsverity_uapi.h | 14 | ||||
-rw-r--r-- | fsveritysetup.h | 13 |
5 files changed, 2 insertions, 371 deletions
diff --git a/cmd_setup.c b/cmd_setup.c index 29848f9..db2e859 100644 --- a/cmd_setup.c +++ b/cmd_setup.c @@ -25,8 +25,6 @@ enum { OPT_SIGNING_KEY, OPT_SIGNING_CERT, OPT_SIGNATURE, - OPT_ELIDE, - OPT_PATCH, }; static const struct option longopts[] = { @@ -36,8 +34,6 @@ static const struct option longopts[] = { {"signing-key", required_argument, NULL, OPT_SIGNING_KEY}, {"signing-cert", required_argument, NULL, OPT_SIGNING_CERT}, {"signature", required_argument, NULL, OPT_SIGNATURE}, - {"elide", required_argument, NULL, OPT_ELIDE}, - {"patch", required_argument, NULL, OPT_PATCH}, {NULL, 0, NULL, 0} }; @@ -247,7 +243,6 @@ static int append_fsverity_descriptor(const struct fsveritysetup_params *params, desc_auth_len += FSVERITY_EXTLEN(params->hash_alg->digest_size); if (params->saltlen) desc_auth_len += FSVERITY_EXTLEN(params->saltlen); - desc_auth_len += total_elide_patch_ext_length(params); desc = buf = xzalloc(desc_auth_len); memcpy(desc->magic, FS_VERITY_MAGIC, sizeof(desc->magic)); @@ -263,7 +258,6 @@ static int append_fsverity_descriptor(const struct fsveritysetup_params *params, auth_ext_count = 1; /* root hash */ if (params->saltlen) auth_ext_count++; - auth_ext_count += params->num_elisions_and_patches; desc->auth_ext_count = cpu_to_le16(auth_ext_count); buf += sizeof(*desc); @@ -272,7 +266,6 @@ static int append_fsverity_descriptor(const struct fsveritysetup_params *params, if (params->saltlen) fsverity_append_extension(&buf, FS_VERITY_EXT_SALT, params->salt, params->saltlen); - append_elide_patch_exts(&buf, params); ASSERT(buf - (void *)desc == desc_auth_len); hash_update(hash, desc, desc_auth_len); @@ -340,10 +333,9 @@ static int fsveritysetup(const char *infile, const char *outfile, struct filedes _out = { .fd = -1 }; struct filedes _tmp = { .fd = -1 }; struct hash_ctx *hash = NULL; - struct filedes *in = &_in, *out = &_out, *src; + struct filedes *in = &_in, *out = &_out; u64 filesize; u64 aligned_filesize; - u64 src_filesize; u64 tree_end_offset; u8 root_hash[FS_VERITY_MAX_DIGEST_SIZE]; u8 measurement[FS_VERITY_MAX_DIGEST_SIZE]; @@ -385,22 +377,10 @@ static int fsveritysetup(const char *infile, const char *outfile, if (!write_zeroes(out, aligned_filesize - filesize)) goto out_err; - if (params->num_elisions_and_patches) { - /* Merkle tree is built over temporary elided/patched file */ - src = &_tmp; - if (!apply_elisions_and_patches(params, in, filesize, - src, &src_filesize)) - goto out_err; - } else { - /* Merkle tree is built over original file */ - src = out; - src_filesize = aligned_filesize; - } - hash = hash_create(params->hash_alg); /* Build the file's Merkle tree and calculate its root hash */ - status = build_merkle_tree(params, hash, src, src_filesize, + status = build_merkle_tree(params, hash, out, aligned_filesize, out, aligned_filesize, &tree_end_offset, root_hash); if (status) @@ -454,8 +434,6 @@ int fsverity_cmd_setup(const struct fsverity_command *cmd, struct fsveritysetup_params params = { .hash_alg = DEFAULT_HASH_ALG, }; - STRING_LIST(elide_opts); - STRING_LIST(patch_opts); int c; int status; @@ -491,12 +469,6 @@ int fsverity_cmd_setup(const struct fsverity_command *cmd, case OPT_SIGNATURE: params.signature_file = optarg; break; - case OPT_ELIDE: - string_list_append(&elide_opts, optarg); - break; - case OPT_PATCH: - string_list_append(&patch_opts, optarg); - break; default: goto out_usage; } @@ -535,15 +507,9 @@ int fsverity_cmd_setup(const struct fsverity_command *cmd, goto out_err; } - if (!load_elisions_and_patches(&elide_opts, &patch_opts, ¶ms)) - goto out_err; - status = fsveritysetup(argv[0], argv[argc - 1], ¶ms); out: free(params.salt); - free_elisions_and_patches(¶ms); - string_list_destroy(&elide_opts); - string_list_destroy(&patch_opts); return status; out_err: diff --git a/elide_patch.c b/elide_patch.c deleted file mode 100644 index 3eed416..0000000 --- a/elide_patch.c +++ /dev/null @@ -1,307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Elide and patch handling for 'fsverity setup' - * - * Copyright (C) 2018 Google LLC - * - * Written by Eric Biggers. - */ - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "fsverity_uapi.h" -#include "fsveritysetup.h" - -/* An elision or a patch */ -struct fsverity_elide_patch { - u64 offset; /* byte offset within the original data */ - u64 length; /* length in bytes */ - bool patch; /* false if elision, true if patch */ - u8 data[]; /* replacement data (if patch=true) */ -}; - -/* Maximum supported patch size, in bytes */ -#define FS_VERITY_MAX_PATCH_SIZE 255 - -/* Parse an --elide=OFFSET,LENGTH option */ -static struct fsverity_elide_patch *parse_elide_option(const char *optarg) -{ - struct fsverity_elide_patch *ext = NULL; - char *sep, *end; - unsigned long long offset; - unsigned long long length; - - sep = strchr(optarg, ','); - if (!sep || sep == optarg) - goto invalid; - errno = 0; - *sep = '\0'; - offset = strtoull(optarg, &end, 10); - *sep = ','; - if (errno || end != sep) - goto invalid; - length = strtoull(sep + 1, &end, 10); - if (errno || *end) - goto invalid; - if (length <= 0 || length > UINT64_MAX - offset) { - error_msg("Invalid length in '--elide=%s'", optarg); - return NULL; - } - ext = xzalloc(sizeof(*ext)); - ext->offset = offset; - ext->length = length; - ext->patch = false; - return ext; - -invalid: - error_msg("Invalid --elide option: '%s'. Must be formatted as OFFSET,LENGTH", - optarg); - return NULL; -} - -/* Parse a --patch=OFFSET,PATCHFILE option */ -static struct fsverity_elide_patch *parse_patch_option(const char *optarg) -{ - struct fsverity_elide_patch *ext = NULL; - struct filedes patchfile = { .fd = -1 }; - char *sep, *end; - unsigned long long offset; - u64 length; - - sep = strchr(optarg, ','); - if (!sep || sep == optarg) - goto invalid; - errno = 0; - *sep = '\0'; - offset = strtoull(optarg, &end, 10); - *sep = ','; - if (errno || end != sep) - goto invalid; - if (!open_file(&patchfile, sep + 1, O_RDONLY, 0)) - goto out; - if (!get_file_size(&patchfile, &length)) - goto out; - if (length <= 0) { - error_msg("patch file '%s' is empty", patchfile.name); - goto out; - } - if (length > FS_VERITY_MAX_PATCH_SIZE) { - error_msg("Patch file '%s' is too long. Max patch size is %d bytes.", - patchfile.name, FS_VERITY_MAX_PATCH_SIZE); - goto out; - } - ext = xzalloc(sizeof(*ext) + length); - ext->offset = offset; - ext->length = length; - ext->patch = true; - if (!full_read(&patchfile, ext->data, length)) { - free(ext); - ext = NULL; - } -out: - filedes_close(&patchfile); - return ext; - -invalid: - error_msg("Invalid --patch option: '%s'. Must be formatted as OFFSET,PATCHFILE", - optarg); - goto out; -} - -/* Sort by increasing offset */ -static int cmp_elide_patch_exts(const void *_p1, const void *_p2) -{ - const struct fsverity_elide_patch *ext1, *ext2; - - ext1 = *(const struct fsverity_elide_patch **)_p1; - ext2 = *(const struct fsverity_elide_patch **)_p2; - - if (ext1->offset > ext2->offset) - return 1; - if (ext1->offset < ext2->offset) - return -1; - return 0; -} - -/* - * Given the lists of --elide and --patch options, validate and load the - * elisions and patches into @params. - */ -bool load_elisions_and_patches(const struct string_list *elide_opts, - const struct string_list *patch_opts, - struct fsveritysetup_params *params) -{ - const size_t num_exts = elide_opts->length + patch_opts->length; - struct fsverity_elide_patch **exts; - size_t i, j; - - if (num_exts == 0) /* Normal case: no elisions or patches */ - return true; - params->num_elisions_and_patches = num_exts; - exts = xzalloc(num_exts * sizeof(exts[0])); - params->elisions_and_patches = exts; - j = 0; - - /* Parse the --elide options */ - for (i = 0; i < elide_opts->length; i++) { - exts[j] = parse_elide_option(elide_opts->strings[i]); - if (!exts[j++]) - return false; - } - - /* Parse the --patch options */ - for (i = 0; i < patch_opts->length; i++) { - exts[j] = parse_patch_option(patch_opts->strings[i]); - if (!exts[j++]) - return false; - } - - /* Sort the elisions and patches by increasing offset */ - qsort(exts, num_exts, sizeof(exts[0]), cmp_elide_patch_exts); - - /* Verify that no elisions or patches overlap */ - for (j = 1; j < num_exts; j++) { - if (exts[j]->offset < - exts[j - 1]->offset + exts[j - 1]->length) { - error_msg("%s at [%"PRIu64", %"PRIu64") overlaps " - "%s at [%"PRIu64", %"PRIu64")", - exts[j - 1]->patch ? "Patch" : "Elision", - exts[j - 1]->offset, - exts[j - 1]->offset + exts[j - 1]->length, - exts[j]->patch ? "patch" : "elision", - exts[j]->offset, - exts[j]->offset + exts[j]->length); - return false; - } - } - return true; -} - -void free_elisions_and_patches(struct fsveritysetup_params *params) -{ - size_t i; - - for (i = 0; i < params->num_elisions_and_patches; i++) - free(params->elisions_and_patches[i]); - free(params->elisions_and_patches); -} - -/* - * Given the original file @in of length @in_length bytes, create a temporary - * file @out_ret and write to it the data with the elisions and patches applied, - * with the end zero-padded to the next block boundary. Returns in - * @out_length_ret the length of the elided/patched file in bytes. - */ -bool apply_elisions_and_patches(const struct fsveritysetup_params *params, - struct filedes *in, u64 in_length, - struct filedes *out_ret, u64 *out_length_ret) -{ - struct fsverity_elide_patch **exts = params->elisions_and_patches; - struct filedes *out = out_ret; - size_t i; - - for (i = 0; i < params->num_elisions_and_patches; i++) { - if (exts[i]->offset + exts[i]->length > in_length) { - error_msg("%s at [%"PRIu64", %"PRIu64") extends beyond end of input file", - exts[i]->patch ? "Patch" : "Elision", - exts[i]->offset, - exts[i]->offset + exts[i]->length); - return false; - } - } - - if (!filedes_seek(in, 0, SEEK_SET)) - return false; - - if (!open_tempfile(out)) - return false; - - for (i = 0; i < params->num_elisions_and_patches; i++) { - printf("Applying %s: offset=%"PRIu64", length=%"PRIu64"\n", - exts[i]->patch ? "patch" : "elision", - exts[i]->offset, exts[i]->length); - - if (!copy_file_data(in, out, exts[i]->offset - in->pos)) - return false; - - if (exts[i]->patch && - !full_write(out, exts[i]->data, exts[i]->length)) - return false; - - if (!filedes_seek(in, exts[i]->length, SEEK_CUR)) - return false; - } - if (!copy_file_data(in, out, in_length - in->pos)) - return false; - if (!write_zeroes(out, ALIGN(out->pos, params->blocksize) - out->pos)) - return false; - *out_length_ret = out->pos; - return true; -} - -/* Calculate the size the elisions and patches will take up when serialized */ -size_t total_elide_patch_ext_length(const struct fsveritysetup_params *params) -{ - size_t total = 0; - size_t i; - - for (i = 0; i < params->num_elisions_and_patches; i++) { - const struct fsverity_elide_patch *ext = - params->elisions_and_patches[i]; - size_t inner_len; - - if (ext->patch) { - inner_len = sizeof(struct fsverity_extension_patch) + - ext->length; - } else { - inner_len = sizeof(struct fsverity_extension_elide); - } - total += FSVERITY_EXTLEN(inner_len); - } - return total; -} - -/* - * Append the elide and patch extensions (if any) to the given buffer. - * The buffer must have enough space; call total_elide_patch_ext_length() first. - */ -void append_elide_patch_exts(void **buf_p, - const struct fsveritysetup_params *params) -{ - void *buf = *buf_p; - size_t i; - union { - struct { - struct fsverity_extension_patch hdr; - u8 data[FS_VERITY_MAX_PATCH_SIZE]; - } patch; - struct fsverity_extension_elide elide; - } u; - - for (i = 0; i < params->num_elisions_and_patches; i++) { - const struct fsverity_elide_patch *ext = - params->elisions_and_patches[i]; - int type; - size_t extlen; - - if (ext->patch) { - type = FS_VERITY_EXT_PATCH; - u.patch.hdr.offset = cpu_to_le64(ext->offset); - ASSERT(ext->length <= sizeof(u.patch.data)); - memcpy(u.patch.data, ext->data, ext->length); - extlen = sizeof(u.patch.hdr) + ext->length; - } else { - type = FS_VERITY_EXT_ELIDE; - u.elide.offset = cpu_to_le64(ext->offset), - u.elide.length = cpu_to_le64(ext->length); - extlen = sizeof(u.elide); - } - fsverity_append_extension(&buf, type, &u, extlen); - } - - *buf_p = buf; -} @@ -41,7 +41,6 @@ static const struct fsverity_command { " fsverity setup INFILE [OUTFILE]\n" " [--hash=HASH_ALG] [--salt=SALT] [--signing-key=KEYFILE]\n" " [--signing-cert=CERTFILE] [--signature=SIGFILE]\n" -" [--patch=OFFSET,PATCHFILE] [--elide=OFFSET,LENGTH]\n" } }; diff --git a/fsverity_uapi.h b/fsverity_uapi.h index 00c64f9..a02d91c 100644 --- a/fsverity_uapi.h +++ b/fsverity_uapi.h @@ -57,8 +57,6 @@ struct fsverity_descriptor { #define FS_VERITY_EXT_ROOT_HASH 1 #define FS_VERITY_EXT_SALT 2 #define FS_VERITY_EXT_PKCS7_SIGNATURE 3 -#define FS_VERITY_EXT_ELIDE 4 -#define FS_VERITY_EXT_PATCH 5 /* Header of each extension (variable-length metadata item) */ struct fsverity_extension { @@ -91,18 +89,6 @@ struct fsverity_digest_disk { __u8 digest[]; }; -/* FS_VERITY_EXT_ELIDE payload */ -struct fsverity_extension_elide { - __le64 offset; - __le64 length; -}; - -/* FS_VERITY_EXT_PATCH payload */ -struct fsverity_extension_patch { - __le64 offset; - /* followed by variable-length patch data */ -}; - /* Fields stored at the very end of the file */ struct fsverity_footer { __le32 desc_reverse_offset; /* distance to fsverity_descriptor */ diff --git a/fsveritysetup.h b/fsveritysetup.h index 282aabd..e84a3a6 100644 --- a/fsveritysetup.h +++ b/fsveritysetup.h @@ -14,8 +14,6 @@ struct fsveritysetup_params { const char *signing_key_file; const char *signing_cert_file; const char *signature_file; - struct fsverity_elide_patch **elisions_and_patches; - size_t num_elisions_and_patches; }; void fsverity_append_extension(void **buf_p, int type, @@ -24,17 +22,6 @@ void fsverity_append_extension(void **buf_p, int type, #define FSVERITY_EXTLEN(inner_len) \ ALIGN(sizeof(struct fsverity_extension) + (inner_len), 8) -/* elide_patch.c */ -bool load_elisions_and_patches(const struct string_list *elide_opts, - const struct string_list *patch_opts, - struct fsveritysetup_params *params); -void free_elisions_and_patches(struct fsveritysetup_params *params); -bool apply_elisions_and_patches(const struct fsveritysetup_params *params, - struct filedes *in, u64 in_length, - struct filedes *out_ret, u64 *out_length_ret); -size_t total_elide_patch_ext_length(const struct fsveritysetup_params *params); -void append_elide_patch_exts(void **buf_p, - const struct fsveritysetup_params *params); /* sign.c */ int append_signed_measurement(struct filedes *out, const struct fsveritysetup_params *params, |