From 0a951da27f1e0ea394d59194dfbaf60820a0eea1 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 23 Mar 2016 13:44:37 +0100 Subject: [PATCH] Disable DIRECT_IO for LUKS header with unaligned keyslots. Fixes issue#287. Such a header is very rare, it is not worth to do more detection here. --- lib/internal.h | 2 ++ lib/luks1/keymanage.c | 10 ++++++++++ lib/utils_device.c | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/lib/internal.h b/lib/internal.h index fb265eef..5d776003 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -75,6 +75,8 @@ int device_block_size(struct device *device); int device_read_ahead(struct device *device, uint32_t *read_ahead); int device_size(struct device *device, uint64_t *size); int device_open(struct device *device, int flags); +void device_disable_direct_io(struct device *device); + enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 }; int device_block_adjust(struct crypt_device *cd, diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 44673c39..16968fbc 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -545,6 +545,16 @@ int LUKS_read_phdr(struct luks_phdr *hdr, if (!r) r = LUKS_check_device_size(ctx, hdr->keyBytes); + /* + * Cryptsetup 1.0.0 did not align keyslots to 4k (very rare version). + * Disable direct-io to avoid possible IO errors if underlying device + * has bigger sector size. + */ + if (!r && hdr->keyblock[0].keyMaterialOffset * SECTOR_SIZE < LUKS_ALIGN_KEYSLOTS) { + log_dbg("Old unaligned LUKS keyslot detected, disabling direct-io."); + device_disable_direct_io(device); + } + close(devfd); return r; } diff --git a/lib/utils_device.c b/lib/utils_device.c index 72899338..8c4d4349 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -530,3 +530,8 @@ size_t size_round_up(size_t size, unsigned int block) size_t s = (size + (block - 1)) / block; return s * block; } + +void device_disable_direct_io(struct device *device) +{ + device->o_direct = 0; +}