aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-05-20 17:03:46 -0700
committerEric Biggers <ebiggers@google.com>2019-05-20 17:03:46 -0700
commite64d479f2975df8e60788264a2d0ab4351b2965f (patch)
tree195dd07299e5fbfec207f9c1cd29d981cbff9e1e
parentb0ebc3e09cbbd899a0a4c8fa462af7197c06296c (diff)
downloadfsverity-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.c38
-rw-r--r--elide_patch.c307
-rw-r--r--fsverity.c1
-rw-r--r--fsverity_uapi.h14
-rw-r--r--fsveritysetup.h13
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, &params))
- goto out_err;
-
status = fsveritysetup(argv[0], argv[argc - 1], &params);
out:
free(params.salt);
- free_elisions_and_patches(&params);
- 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;
-}
diff --git a/fsverity.c b/fsverity.c
index a463c7f..700ae15 100644
--- a/fsverity.c
+++ b/fsverity.c
@@ -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,