[PATCH] cryptsetup: add support for the "fix_padding" option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds support for fixed padding to cryptsetup.

* Cryptsetup will accept superblocks version 4.
* If the dm-integrity target version is greater than 1.4, cryptsetup will 
  add a flag "fix_padding" to the dm-integrity target arguments.

There is still one quirk: if we have an old libdm without 
DM_DEVICE_GET_TARGET_VERSION and if dm-integrity module is not loaded, 
cryptsetup will not detect that it can use the "fix_padding" option.

Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx>

---
 lib/integrity/integrity.c |    7 +++----
 lib/integrity/integrity.h |    2 ++
 lib/libdevmapper.c        |   20 +++++++++++++++++++-
 lib/utils_dm.h            |    6 +++++-
 4 files changed, 29 insertions(+), 6 deletions(-)

Index: cryptsetup/lib/integrity/integrity.c
===================================================================
--- cryptsetup.orig/lib/integrity/integrity.c	2019-11-12 20:09:30.000000000 +0100
+++ cryptsetup/lib/integrity/integrity.c	2019-11-12 21:09:05.000000000 +0100
@@ -41,8 +41,7 @@ static int INTEGRITY_read_superblock(str
 	if (read_lseek_blockwise(devfd, device_block_size(cd, device),
 		device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
 	    memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
-	    (sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
-	     sb->version != SB_VERSION_3)) {
+	    sb->version < SB_VERSION_1 || sb->version > SB_VERSION_4) {
 		log_std(cd, "No integrity superblock detected on %s.\n",
 			device_path(device));
 		r = -EINVAL;
@@ -203,7 +202,7 @@ int INTEGRITY_create_dmd_device(struct c
 	if (r < 0)
 		return r;
 
-	return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
+	return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
 			crypt_metadata_device(cd), crypt_data_device(cd),
 			crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
 			crypt_get_sector_size(cd), vk, journal_crypt_key,
@@ -289,7 +288,7 @@ int INTEGRITY_format(struct crypt_device
 	if (params && params->integrity_key_size)
 		vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
 
-	r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
+	r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
 			crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
 			crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
 			journal_crypt_key, journal_mac_key, params);
Index: cryptsetup/lib/integrity/integrity.h
===================================================================
--- cryptsetup.orig/lib/integrity/integrity.h	2019-11-12 20:09:30.000000000 +0100
+++ cryptsetup/lib/integrity/integrity.h	2019-11-12 20:12:54.000000000 +0100
@@ -34,10 +34,12 @@ struct crypt_dm_active_device;
 #define SB_VERSION_1	1
 #define SB_VERSION_2	2
 #define SB_VERSION_3	3
+#define SB_VERSION_4	4
 
 #define SB_FLAG_HAVE_JOURNAL_MAC	(1 << 0)
 #define SB_FLAG_RECALCULATING		(1 << 1) /* V2 only */
 #define SB_FLAG_DIRTY_BITMAP		(1 << 2) /* V3 only */
+#define SB_FLAG_FIXED_PADDING		(1 << 3) /* V4 only */
 
 struct superblock {
 	uint8_t magic[8];
Index: cryptsetup/lib/libdevmapper.c
===================================================================
--- cryptsetup.orig/lib/libdevmapper.c	2019-11-12 20:09:30.000000000 +0100
+++ cryptsetup/lib/libdevmapper.c	2019-11-13 12:42:39.000000000 +0100
@@ -218,6 +218,9 @@ static void _dm_set_integrity_compat(str
 	if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
 		_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
 
+	if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
+		_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
+
 	_dm_integrity_checked = true;
 }
 
@@ -866,6 +869,11 @@ static char *get_dm_integrity_params(con
 		strncat(features, feature, sizeof(features) - strlen(features) - 1);
 		crypt_safe_free(hexkey);
 	}
+	if (tgt->u.integrity.fix_padding) {
+		num_options++;
+		snprintf(feature, sizeof(feature), "fix_padding ");
+		strncat(features, feature, sizeof(features) - strlen(features) - 1);
+	}
 
 	if (flags & CRYPT_ACTIVATE_RECALCULATE) {
 		num_options++;
@@ -2334,6 +2342,8 @@ static int _dm_target_query_integrity(st
 				}
 			} else if (!strcmp(arg, "recalculate")) {
 				*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
+			} else if (!strcmp(arg, "fix_padding")) {
+				tgt->u.integrity.fix_padding = true;
 			} else /* unknown option */
 				goto err;
 		}
@@ -2865,16 +2875,21 @@ int dm_verity_target_set(struct dm_targe
 	return 0;
 }
 
-int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
+int dm_integrity_target_set(struct crypt_device *cd,
+			struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 			struct device *meta_device,
 		        struct device *data_device, uint64_t tag_size, uint64_t offset,
 			uint32_t sector_size, struct volume_key *vk,
 			struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
 			const struct crypt_params_integrity *ip)
 {
+	uint32_t dmi_flags;
+
 	if (!data_device)
 		return -EINVAL;
 
+	_dm_check_versions(cd, DM_INTEGRITY);
+
 	tgt->type = DM_INTEGRITY;
 	tgt->direction = TARGET_SET;
 	tgt->offset = seg_offset;
@@ -2890,6 +2905,9 @@ int dm_integrity_target_set(struct dm_ta
 	tgt->u.integrity.journal_crypt_key = journal_crypt_key;
 	tgt->u.integrity.journal_integrity_key = journal_mac_key;
 
+	if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) && dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)
+		tgt->u.integrity.fix_padding = true;
+
 	if (ip) {
 		tgt->u.integrity.journal_size = ip->journal_size;
 		tgt->u.integrity.journal_watermark = ip->journal_watermark;
Index: cryptsetup/lib/utils_dm.h
===================================================================
--- cryptsetup.orig/lib/utils_dm.h	2019-11-12 20:09:30.000000000 +0100
+++ cryptsetup/lib/utils_dm.h	2019-11-12 21:09:25.000000000 +0100
@@ -64,6 +64,7 @@ static inline uint32_t act2dmflags(uint3
 #define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
 #define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
 #define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
+#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */
 
 typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
 enum tdirection { TARGET_SET = 1, TARGET_QUERY };
@@ -138,6 +139,8 @@ struct dm_target {
 		struct volume_key *journal_crypt_key;
 
 		struct device *meta_device;
+
+		bool fix_padding;
 	} integrity;
 	struct {
 		uint64_t offset;
@@ -177,7 +180,8 @@ int dm_verity_target_set(struct dm_targe
 	struct device *data_device, struct device *hash_device, struct device *fec_device,
 	const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
 	uint64_t hash_blocks, struct crypt_params_verity *vp);
-int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
+int dm_integrity_target_set(struct crypt_device *cd,
+	struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 	struct device *meta_device,
 	struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
 	struct volume_key *vk,

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel





[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux