[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <C8AA8C7B-505E-49E8-AE47-C24843E74543@netflix.com>
Date: Thu, 9 Aug 2012 00:40:23 +0000
From: Wesley Miaw <wmiaw@...flix.com>
To: Milan Broz <mbroz@...hat.com>
CC: Mikulas Patocka <mpatocka@...hat.com>,
device-mapper development <dm-devel@...hat.com>,
Alasdair Kergon <agk@...hat.com>,
"msb@...gle.com" <msb@...gle.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Will Drewry™ <w@...gle.com>
Subject: Re: [dm-devel] [PATCH v2 2/2] dm: verity support data device offset
(Linux 3.4.7)
On Aug 8, 2012, at 1:56 PM, Milan Broz wrote:
> On 08/08/2012 10:46 PM, Wesley Miaw wrote:
>
>> I did modify veritysetup on my own so the format and verify commands will work with regular files on disk instead of having to mount through loop devices.
>
> Which veritysetup? In upstream (cryptsetup repository) it allocates loop automatically.
> (And for userspace verification it doesn't need loop at all.)
>
> Anyway, please send a patch for userspace as well then ;-)
This isn't as polished because I pretty much just added support to do what I needed. I'm not sure if the LKML is the right place to post, so let me know if I should send this somewhere else.
Your previous email implied that veritysetup would need a way to determine if the data offset option is supported; I did not modify veritysetup to support this idea as I didn't need it.
Thanks.
From: Wesley Miaw <wmiaw@...flix.com>
Allow veritysetup format and verify commands to directly operate on regular
files instead of requiring mounts through loop devices.
Signed-off-by: Wesley Miaw <wmiaw@...flix.com>
---
cryptsetup/lib/internal.h | 1
cryptsetup/lib/libcryptsetup.h | 22 ++++
cryptsetup/lib/libcryptsetup.sym | 2
cryptsetup/lib/setup.c | 133 ++++++++++++++++++++++++++++-
cryptsetup/lib/utils.c | 12 ++
cryptsetup/src/veritysetup.c | 23 +++--
6 files changed, 183 insertions(+), 10 deletions(-)
--- a/cryptsetup/lib/internal.h 2012-08-08 17:11:20.366392301 -0700
+++ b/cryptsetup/lib/internal.h 2012-08-06 16:17:35.154719491 -0700
@@ -76,6 +76,7 @@ ssize_t read_blockwise(int fd, void *_bu
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
int device_ready(struct crypt_device *cd, const char *device, int mode);
int device_size(const char *device, uint64_t *size);
+int file_size(const char *filename, uint64_t *size);
unsigned crypt_getpagesize(void);
--- a/cryptsetup/lib/libcryptsetup.h 2012-08-08 17:11:20.375392929 -0700
+++ b/cryptsetup/lib/libcryptsetup.h 2012-08-06 16:17:35.159720699 -0700
@@ -56,6 +57,19 @@ struct crypt_device; /* crypt device han
int crypt_init(struct crypt_device **cd, const char *device);
/**
+ * Initial crypt device handle from a file and check if provided file exists.
+ *
+ * @param cd Returns pointer to crypt device handle.
+ * @param filename Path to the backing file.
+ *
+ * @return @e 0 on success or negative errno value otherwise.
+ *
+ * @note Note that logging is not initialized here, possible messages uses
+ * default log function.
+ */
+int crypt_initfile(struct crypt_device **cd, const char *filename);
+
+/**
* Initialize crypt device handle from provided active device name,
* and, optionally, from separate metadata (header) device
* and check if provided device exists.
@@ -237,6 +251,15 @@ void crypt_set_password_verify(struct cr
int crypt_set_data_device(struct crypt_device *cd, const char *device);
/**
+ * Set data file
+ * For VERITY it is data file when hash device is separated.
+ *
+ * @param cd crypt device handle
+ * @param filename path to data file
+ */
+int crypt_set_data_file(struct crypt_device *cd, const char *device);
+
+/**
* @defgroup rng "Cryptsetup RNG"
*
* @addtogroup rng
--- a/cryptsetup/lib/libcryptsetup.sym 2012-08-08 17:11:20.375392930 -0700
+++ b/cryptsetup/lib/libcryptsetup.sym 2012-08-06 16:17:35.160720941 -0700
@@ -1,6 +1,7 @@
CRYPTSETUP_1.0 {
global:
crypt_init;
+ crypt_initfile;
crypt_init_by_name;
crypt_init_by_name_and_header;
crypt_set_log_callback;
@@ -13,6 +14,7 @@ CRYPTSETUP_1.0 {
crypt_set_password_verify;
crypt_set_uuid;
crypt_set_data_device;
+ crypt_set_data_file;
crypt_memory_lock;
crypt_format;
--- a/cryptsetup/lib/setup.c 2012-08-08 17:11:20.428396640 -0700
+++ b/cryptsetup/lib/setup.c 2012-08-06 16:17:35.192728669 -0700
@@ -25,6 +25,8 @@
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "libcryptsetup.h"
#include "luks.h"
@@ -585,6 +587,56 @@ bad:
return r;
}
+int crypt_initfile(struct crypt_device **cd, const char *filename)
+{
+ struct crypt_device *h = NULL;
+ int fd;
+ struct stat st;
+ int r;
+
+ if (!cd)
+ return -EINVAL;
+
+ if (stat(filename, &st) < 0) {
+ log_err(NULL, _("File %s doesn't exist or access denied.\n"), filename);
+ return -EINVAL;
+ }
+
+ log_dbg("Trying to open and write file %s.", filename);
+ fd = open(filename, O_RDWR);
+ if (fd < 0) {
+ log_err(NULL, _("Cannot open file %s for writeable access.\n"), filename);
+ return -EINVAL;
+ }
+ close(fd);
+
+ log_dbg("Allocating crypt device %s context.", filename);
+
+ if (!(h = malloc(sizeof(struct crypt_device))))
+ return -ENOMEM;
+
+ memset(h, 0, sizeof(*h));
+ h->loop_device_fd = -1;
+ h->loop_metadata_device_fd = -1;
+ h->device = strdup(filename);
+ if (!h->device) {
+ r = -ENOMEM;
+ goto bad;
+ }
+ h->iteration_time = 1000;
+ h->password_verify = 0;
+ h->tries = 3;
+ h->rng_type = crypt_random_default_key_rng();
+ *cd = h;
+ return 0;
+bad:
+ if (h) {
+ free(h->device);
+ }
+ free(h);
+ return r;
+}
+
static int crypt_check_data_device_size(struct crypt_device *cd)
{
int r;
@@ -606,6 +658,27 @@ static int crypt_check_data_device_size(
return r;
}
+static int crypt_check_data_file_size(struct crypt_device *cd)
+{
+ int r;
+ uint64_t size, size_min;
+
+ /* Check data device size, require at least one sector */
+ size_min = crypt_get_data_offset(cd) << SECTOR_SHIFT ?: SECTOR_SIZE;
+
+ r = file_size(crypt_get_device_name(cd), &size);
+ if (r < 0)
+ return r;
+
+ if (size < size_min) {
+ log_err(cd, _("Header detected but device %s is too small.\n"),
+ crypt_get_device_name(cd));
+ return -EINVAL;
+ }
+
+ return r;
+}
+
int crypt_set_data_device(struct crypt_device *cd, const char *device)
{
char *data_device = NULL;
@@ -641,6 +714,52 @@ int crypt_set_data_device(struct crypt_d
return crypt_check_data_device_size(cd);
}
+int crypt_set_data_file(struct crypt_device *cd, const char *filename)
+{
+ int fd;
+ struct stat st;
+
+ log_dbg("Setting ciphertext data file to %s.", filename ?: "(none");
+
+ if (!isVERITY(cd->type)) {
+ log_err(cd, _("This operation is not supported for this device type.\n"));
+ return -EINVAL;
+ }
+
+ /* metadata device must be set */
+ if (!cd->device || !filename)
+ return -EINVAL;
+
+ if (stat(filename, &st) < 0) {
+ log_err(NULL, _("File %s doesn't exist or access denied.\n"), filename);
+ return -EINVAL;
+ }
+
+ log_dbg("Trying to open and read file %s.", filename);
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ log_err(NULL, _("Cannot open file %s for read access.\n"), filename);
+ return -EINVAL;
+ }
+ close(fd);
+
+ if (!cd->metadata_device) {
+ cd->metadata_device = cd->device;
+ cd->loop_metadata_device_fd = cd->loop_device_fd;
+ } else {
+ free(cd->device);
+ if (cd->loop_device_fd != -1)
+ close(cd->loop_device_fd);
+ }
+
+ cd->device = strdup(filename);
+ if (!cd->device)
+ return -ENOMEM;
+ cd->loop_device_fd = -1;
+
+ return crypt_check_data_file_size(cd);
+}
+
static int _crypt_load_luks1(struct crypt_device *cd, int require_header, int repair)
{
struct luks_phdr hdr;
@@ -1080,12 +1199,18 @@ static int _crypt_format_verity(struct c
return -ENOMEM;
r = crypt_set_data_device(cd, params->data_device);
- if (r)
- return r;
+ if (r) {
+ r = crypt_set_data_file(cd, params->data_device);
+ if (r)
+ return r;
+ }
if (!params->data_size) {
r = device_size(cd->device, &data_device_size);
- if (r < 0)
- return r;
+ if (r < 0) {
+ r = file_size(cd->device, &data_device_size);
+ if (r < 0)
+ return r;
+ }
cd->verity_hdr.data_size = data_device_size / params->data_block_size;
} else
--- a/cryptsetup/lib/utils.c 2012-08-08 17:11:20.433396990 -0700
+++ b/cryptsetup/lib/utils.c 2012-08-06 16:17:35.202731084 -0700
@@ -316,6 +316,18 @@ int device_size(const char *device, uint
return r;
}
+int file_size(const char *filename, uint64_t *size)
+{
+ struct stat st;
+
+ if (stat(filename, &st) < 0)
+ return -EINVAL;
+
+ *size = (uint64_t)st.st_size;
+
+ return 0;
+}
+
static int get_device_infos(const char *device, enum devcheck device_check,
int *readonly, uint64_t *size)
{
--- a/cryptsetup/src/veritysetup.c 2012-08-08 17:11:20.942432624 -0700
+++ b/cryptsetup/src/veritysetup.c 2012-08-06 16:17:35.235739053 -0700
@@ -142,8 +142,12 @@ static int action_format(int arg)
uint32_t flags = CRYPT_VERITY_CREATE_HASH;
int r;
- if ((r = crypt_init(&cd, action_argv[1])))
- goto out;
+ r = crypt_init(&cd, action_argv[1]);
+ if (r < 0) {
+ r = crypt_initfile(&cd, action_argv[1]);
+ if (r < 0)
+ goto out;
+ }
if (!use_superblock)
flags |= CRYPT_VERITY_NO_HEADER;
@@ -174,8 +178,12 @@ static int _activate(const char *dm_devi
ssize_t hash_size;
int r;
- if ((r = crypt_init(&cd, hash_device)))
- goto out;
+ r = crypt_init(&cd, hash_device);
+ if (r < 0) {
+ r = crypt_initfile(&cd, hash_device);
+ if (r < 0)
+ goto out;
+ }
if (use_superblock) {
params.flags = flags;
@@ -190,8 +198,11 @@ static int _activate(const char *dm_devi
if (r < 0)
goto out;
r = crypt_set_data_device(cd, data_device);
- if (r < 0)
- goto out;
+ if (r < 0) {
+ r = crypt_set_data_file(cd, data_device);
+ if (r < 0)
+ goto out;
+ }
hash_size = crypt_get_volume_key_size(cd);
if (crypt_hex_to_bytes(root_hash, &root_hash_bytes, 0) != hash_size) {
Download attachment "signature.asc" of type "application/pgp-signature" (496 bytes)
Powered by blists - more mailing lists