linux-fscrypt.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [fsverity-utils RFC PATCH 0/2] Add dump_metadata subcommand
@ 2021-01-15 18:24 Eric Biggers
  2021-01-15 18:24 ` [fsverity-utils RFC PATCH 1/2] Upgrade to latest fsverity_uapi.h Eric Biggers
  2021-01-15 18:24 ` [fsverity-utils RFC PATCH 2/2] programs/fsverity: Add dump_metadata subcommand Eric Biggers
  0 siblings, 2 replies; 3+ messages in thread
From: Eric Biggers @ 2021-01-15 18:24 UTC (permalink / raw)
  To: linux-fscrypt
  Cc: linux-ext4, linux-f2fs-devel, Theodore Ts'o, Jaegeuk Kim,
	Victor Hsieh

Add new subcommand 'fsverity dump_metadata' which wraps the proposed
FS_IOC_READ_VERITY_METADATA ioctl
(https://lkml.kernel.org/linux-fscrypt/20210115181819.34732-1-ebiggers@kernel.org/T/#u).

This subcommand is useful for xfstests and for debugging.

Eric Biggers (2):
  Upgrade to latest fsverity_uapi.h
  programs/fsverity: Add dump_metadata subcommand

 Makefile                     |   1 +
 common/fsverity_uapi.h       |  14 +++
 programs/cmd_dump_metadata.c | 167 +++++++++++++++++++++++++++++++++++
 programs/fsverity.c          |   6 ++
 programs/fsverity.h          |   6 ++
 5 files changed, 194 insertions(+)
 create mode 100644 programs/cmd_dump_metadata.c

-- 
2.30.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [fsverity-utils RFC PATCH 1/2] Upgrade to latest fsverity_uapi.h
  2021-01-15 18:24 [fsverity-utils RFC PATCH 0/2] Add dump_metadata subcommand Eric Biggers
@ 2021-01-15 18:24 ` Eric Biggers
  2021-01-15 18:24 ` [fsverity-utils RFC PATCH 2/2] programs/fsverity: Add dump_metadata subcommand Eric Biggers
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Biggers @ 2021-01-15 18:24 UTC (permalink / raw)
  To: linux-fscrypt
  Cc: linux-ext4, linux-f2fs-devel, Theodore Ts'o, Jaegeuk Kim,
	Victor Hsieh

From: Eric Biggers <ebiggers@google.com>

Add the FS_IOC_READ_VERITY_METADATA ioctl.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/fsverity_uapi.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/common/fsverity_uapi.h b/common/fsverity_uapi.h
index a739c9a..c59a897 100644
--- a/common/fsverity_uapi.h
+++ b/common/fsverity_uapi.h
@@ -85,7 +85,21 @@ struct fsverity_formatted_digest {
 	__u8 digest[];
 };
 
+#define FS_VERITY_METADATA_TYPE_MERKLE_TREE	1
+#define FS_VERITY_METADATA_TYPE_DESCRIPTOR	2
+#define FS_VERITY_METADATA_TYPE_SIGNATURE	3
+
+struct fsverity_read_metadata_arg {
+	__u64 metadata_type;
+	__u64 offset;
+	__u64 length;
+	__u64 buf_ptr;
+	__u64 __reserved;
+};
+
 #define FS_IOC_ENABLE_VERITY	_IOW('f', 133, struct fsverity_enable_arg)
 #define FS_IOC_MEASURE_VERITY	_IOWR('f', 134, struct fsverity_digest)
+#define FS_IOC_READ_VERITY_METADATA \
+	_IOWR('f', 135, struct fsverity_read_metadata_arg)
 
 #endif /* _UAPI_LINUX_FSVERITY_H */
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [fsverity-utils RFC PATCH 2/2] programs/fsverity: Add dump_metadata subcommand
  2021-01-15 18:24 [fsverity-utils RFC PATCH 0/2] Add dump_metadata subcommand Eric Biggers
  2021-01-15 18:24 ` [fsverity-utils RFC PATCH 1/2] Upgrade to latest fsverity_uapi.h Eric Biggers
@ 2021-01-15 18:24 ` Eric Biggers
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Biggers @ 2021-01-15 18:24 UTC (permalink / raw)
  To: linux-fscrypt
  Cc: linux-ext4, linux-f2fs-devel, Theodore Ts'o, Jaegeuk Kim,
	Victor Hsieh

From: Eric Biggers <ebiggers@google.com>

Add a 'fsverity dump_metadata' subcommand which calls
FS_IOC_READ_VERITY_METADATA on a file and prints the returned metadata
to stdout.  There are three subsubcommands, one for each type of
metadata that can be read using the ioctl:

	fsverity dump_metadata merkle_tree FILE
	fsverity dump_metadata descriptor FILE
	fsverity dump_metadata signature FILE

By default the whole metadata item is dumped.  --length and --offset can
be specified to dump only a particular range of the item.

This subcommand will be used by xfstests to test the
FS_IOC_READ_VERITY_METADATA ioctl.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 Makefile                     |   1 +
 programs/cmd_dump_metadata.c | 167 +++++++++++++++++++++++++++++++++++
 programs/fsverity.c          |   6 ++
 programs/fsverity.h          |   6 ++
 4 files changed, 180 insertions(+)
 create mode 100644 programs/cmd_dump_metadata.c

diff --git a/Makefile b/Makefile
index 0354f62..fd28b06 100644
--- a/Makefile
+++ b/Makefile
@@ -160,6 +160,7 @@ FSVERITY_PROG_OBJ := $(PROG_COMMON_OBJ)		\
 		     programs/fsverity.o
 ifneq ($(MINGW),1)
 FSVERITY_PROG_OBJ += \
+		     programs/cmd_dump_metadata.o \
 		     programs/cmd_enable.o	\
 		     programs/cmd_measure.o
 endif
diff --git a/programs/cmd_dump_metadata.c b/programs/cmd_dump_metadata.c
new file mode 100644
index 0000000..9b249ba
--- /dev/null
+++ b/programs/cmd_dump_metadata.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: MIT
+/*
+ * The 'fsverity dump_metadata' command
+ *
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+#include "fsverity.h"
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+static const struct option longopts[] = {
+	{"offset",	required_argument, NULL, OPT_OFFSET},
+	{"length",	required_argument, NULL, OPT_LENGTH},
+	{NULL, 0, NULL, 0}
+};
+
+static const struct {
+	const char *name;
+	int val;
+} metadata_types[] = {
+	{"merkle_tree", FS_VERITY_METADATA_TYPE_MERKLE_TREE},
+	{"descriptor", FS_VERITY_METADATA_TYPE_DESCRIPTOR},
+	{"signature", FS_VERITY_METADATA_TYPE_SIGNATURE},
+};
+
+static bool parse_metadata_type(const char *name, __u64 *val_ret)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(metadata_types); i++) {
+		if (strcmp(name, metadata_types[i].name) == 0) {
+			*val_ret = metadata_types[i].val;
+			return true;
+		}
+	}
+	error_msg("unknown metadata type: %s", name);
+	fputs("       Expected", stderr);
+	for (i = 0; i < ARRAY_SIZE(metadata_types); i++) {
+		if (i != 0 && ARRAY_SIZE(metadata_types) > 2)
+			putc(',', stderr);
+		putc(' ', stderr);
+		if (i != 0 && i == ARRAY_SIZE(metadata_types) - 1)
+			fputs("or ", stderr);
+		fprintf(stderr, "\"%s\"", metadata_types[i].name);
+	}
+	fprintf(stderr, "\n");
+	return false;
+}
+
+/* Dump the fs-verity metadata of the given file. */
+int fsverity_cmd_dump_metadata(const struct fsverity_command *cmd,
+			       int argc, char *argv[])
+{
+	bool offset_specified = false;
+	bool length_specified = false;
+	struct filedes file = { .fd = -1 };
+	struct filedes stdout_filedes = { .fd = STDOUT_FILENO,
+					  .name = "stdout" };
+	/*
+	 * FS_VERITY_METADATA_TYPE_MERKLE_TREE requires Merkle tree block
+	 * alignment.  Use a 64K buffer which should always be enough.
+	 */
+	struct fsverity_read_metadata_arg arg = { .length = 65536 };
+	void *buf = NULL;
+	char *tmp;
+	int c;
+	int status;
+	int bytes_read;
+
+	while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
+		switch (c) {
+		case OPT_OFFSET:
+			if (offset_specified) {
+				error_msg("--offset can only be specified once");
+				goto out_usage;
+			}
+			errno = 0;
+			arg.offset = strtoull(optarg, &tmp, 10);
+			if (errno || *tmp) {
+				error_msg("invalid value for --offset");
+				goto out_usage;
+			}
+			offset_specified = true;
+			break;
+		case OPT_LENGTH:
+			if (length_specified) {
+				error_msg("--length can only be specified once");
+				goto out_usage;
+			}
+			errno = 0;
+			arg.length = strtoull(optarg, &tmp, 10);
+			if (errno || *tmp || arg.length > SIZE_MAX) {
+				error_msg("invalid value for --length");
+				goto out_usage;
+			}
+			length_specified = true;
+			break;
+		default:
+			goto out_usage;
+		}
+	}
+
+	argv += optind;
+	argc -= optind;
+
+	if (argc != 2)
+		goto out_usage;
+
+	if (!parse_metadata_type(argv[0], &arg.metadata_type))
+		goto out_usage;
+
+	if (length_specified && !offset_specified) {
+		error_msg("--length specified without --offset");
+		goto out_usage;
+	}
+	if (offset_specified && !length_specified) {
+		error_msg("--offset specified without --length");
+		goto out_usage;
+	}
+
+	buf = xzalloc(arg.length);
+	arg.buf_ptr = (uintptr_t)buf;
+
+	if (!open_file(&file, argv[1], O_RDONLY, 0))
+		goto out_err;
+
+	/*
+	 * If --offset and --length were specified, then do only the single read
+	 * requested.  Otherwise read until EOF.
+	 */
+	do {
+		bytes_read = ioctl(file.fd, FS_IOC_READ_VERITY_METADATA, &arg);
+		if (bytes_read < 0) {
+			error_msg_errno("FS_IOC_READ_VERITY_METADATA failed on '%s'",
+					file.name);
+			goto out_err;
+		}
+		if (bytes_read == 0)
+			break;
+		if (!full_write(&stdout_filedes, buf, bytes_read))
+			goto out_err;
+		arg.offset += bytes_read;
+	} while (!length_specified);
+
+	status = 0;
+out:
+	free(buf);
+	filedes_close(&file);
+	return status;
+
+out_err:
+	status = 1;
+	goto out;
+
+out_usage:
+	usage(cmd, stderr);
+	status = 2;
+	goto out;
+}
diff --git a/programs/fsverity.c b/programs/fsverity.c
index b911b2e..1168430 100644
--- a/programs/fsverity.c
+++ b/programs/fsverity.c
@@ -29,6 +29,12 @@ static const struct fsverity_command {
 "               [--hash-alg=HASH_ALG] [--block-size=BLOCK_SIZE] [--salt=SALT]\n"
 "               [--compact] [--for-builtin-sig]\n"
 #ifndef _WIN32
+	}, {
+		.name = "dump_metadata",
+		.func = fsverity_cmd_dump_metadata,
+		.short_desc = "Dump the fs-verity metadata of the given file",
+		.usage_str =
+"    fsverity dump_metadata TYPE FILE [--offset=OFFSET] [--length=LENGTH]\n"
 	}, {
 		.name = "enable",
 		.func = fsverity_cmd_enable,
diff --git a/programs/fsverity.h b/programs/fsverity.h
index 45c4fe1..9785013 100644
--- a/programs/fsverity.h
+++ b/programs/fsverity.h
@@ -27,6 +27,8 @@ enum {
 	OPT_FOR_BUILTIN_SIG,
 	OPT_HASH_ALG,
 	OPT_KEY,
+	OPT_LENGTH,
+	OPT_OFFSET,
 	OPT_SALT,
 	OPT_SIGNATURE,
 };
@@ -37,6 +39,10 @@ struct fsverity_command;
 int fsverity_cmd_digest(const struct fsverity_command *cmd,
 			int argc, char *argv[]);
 
+/* cmd_dump_metadata.c */
+int fsverity_cmd_dump_metadata(const struct fsverity_command *cmd,
+			       int argc, char *argv[]);
+
 /* cmd_enable.c */
 int fsverity_cmd_enable(const struct fsverity_command *cmd,
 			int argc, char *argv[]);
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-01-15 18:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-15 18:24 [fsverity-utils RFC PATCH 0/2] Add dump_metadata subcommand Eric Biggers
2021-01-15 18:24 ` [fsverity-utils RFC PATCH 1/2] Upgrade to latest fsverity_uapi.h Eric Biggers
2021-01-15 18:24 ` [fsverity-utils RFC PATCH 2/2] programs/fsverity: Add dump_metadata subcommand Eric Biggers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).