From 957201e7586f16f11106d7cde23289401d14d47b Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sun, 8 Dec 2013 17:48:55 +0100 Subject: [PATCH] Fix reencryption tool to work with 4k devices. See https://bugzilla.redhat.com/show_bug.cgi?id=1029032#c7 Thanks to Ondra Kozina to figure this out. --- src/cryptsetup_reencrypt.c | 19 +++++++++----- tests/reencryption-compat-test | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/cryptsetup_reencrypt.c b/src/cryptsetup_reencrypt.c index c725968f..6349cb50 100644 --- a/src/cryptsetup_reencrypt.c +++ b/src/cryptsetup_reencrypt.c @@ -122,6 +122,12 @@ static int alignment(int fd) return alignment; } +static size_t pagesize(void) +{ + long r = sysconf(_SC_PAGESIZE); + return r < 0 ? 4096 : (size_t)r; +} + /* Depends on the first two fields of LUKS1 header format, magic and version */ static int device_check(struct reenc_ctx *rc, header_magic set_magic) { @@ -129,6 +135,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) int r, devfd; ssize_t s; uint16_t version; + size_t buf_size = pagesize(); devfd = open(rc->device, O_RDWR | O_EXCL | O_DIRECT); if (devfd == -1) { @@ -146,14 +153,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) goto out; } - if (posix_memalign((void *)&buf, alignment(devfd), SECTOR_SIZE)) { + if (posix_memalign((void *)&buf, alignment(devfd), buf_size)) { log_err(_("Allocation of aligned memory failed.\n")); r = -ENOMEM; goto out; } - s = read(devfd, buf, SECTOR_SIZE); - if (s < 0 || s != SECTOR_SIZE) { + s = read(devfd, buf, buf_size); + if (s < 0 || s != buf_size) { log_err(_("Cannot read device %s.\n"), rc->device); r = -EIO; goto out; @@ -184,8 +191,8 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) if (!r) { if (lseek(devfd, 0, SEEK_SET) == -1) goto out; - s = write(devfd, buf, SECTOR_SIZE); - if (s < 0 || s != SECTOR_SIZE) { + s = write(devfd, buf, buf_size); + if (s < 0 || s != buf_size) { log_err(_("Cannot write device %s.\n"), rc->device); r = -EIO; } @@ -193,7 +200,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) log_dbg("LUKS signature check failed for %s.", rc->device); out: if (buf) - memset(buf, 0, SECTOR_SIZE); + memset(buf, 0, buf_size); free(buf); close(devfd); return r; diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test index 1eda5af1..676d3a6b 100755 --- a/tests/reencryption-compat-test +++ b/tests/reencryption-compat-test @@ -12,6 +12,13 @@ PWD1="93R4P4pIqAH8" PWD2="1cND4319812f" PWD3="1-9Qu5Ejfnqv" + +function del_scsi_device() +{ + rmmod scsi_debug 2>/dev/null + sleep 2 +} + function remove_mapping() { [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 @@ -19,6 +26,7 @@ function remove_mapping() [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 rm -f $IMG $ORIG_IMG $KEY1 >/dev/null 2>&1 LOOPDEV1="" + del_scsi_device } function fail() @@ -35,6 +43,19 @@ function skip() exit 0 } +function add_scsi_device() { + del_scsi_device + modprobe scsi_debug $@ + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 0 + fi + + sleep 2 + SCSI_DEV="/dev/"$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." +} + function open_crypt() { if [ -n "$1" ] ; then @@ -124,6 +145,21 @@ function check_slot() #space separeted list of ENABLED key slots return 0 } +function simple_scsi_reenc() +{ + echo -n "$1" + echo $PWD1 | $CRYPTSETUP luksFormat -i1 $SCSI_DEV || fail + + echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail + HASH=$(sha256sum /dev/mapper/$DEV_NAME | cut -d' ' -f 1) + $CRYPTSETUP luksClose $DEV_NAME || fail + + echo $PWD1 | $REENC -q -i 1 $SCSI_DEV || fail + + echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail + check_hash_dev /dev/mapper/$DEV_NAME $HASH + $CRYPTSETUP luksClose $DEV_NAME || fail +} [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped." @@ -210,5 +246,14 @@ echo "[6] Reencryption using all active keyslots" echo -e "$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD3" | $REENC -q $LOOPDEV1 || fail check_slot 0 1 2 3 4 5 6 7 || fail "All keyslots expected to be enabled" +echo "[7] Reencryption of block devices with different block size" +add_scsi_device sector_size=512 dev_size_mb=8 +simple_scsi_reenc "[512 sector]" +add_scsi_device sector_size=4096 dev_size_mb=8 +simple_scsi_reenc "[4096 sector]" +add_scsi_device sector_size=512 physblk_exp=3 dev_size_mb=8 +simple_scsi_reenc "[4096/512 sector]" +echo "[OK]" + remove_mapping exit 0