diff --git a/lib/setup.c b/lib/setup.c index a07c29cd..ef4d4539 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1321,6 +1321,7 @@ static int _crypt_format_plain(struct crypt_device *cd, struct crypt_params_plain *params) { unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE; + uint64_t dev_size; if (!cipher || !cipher_mode) { log_err(cd, _("Invalid plain crypt parameters.")); @@ -1347,6 +1348,15 @@ static int _crypt_format_plain(struct crypt_device *cd, return -EINVAL; } + if (sector_size > SECTOR_SIZE && !device_size(cd->device, &dev_size)) { + if (params && params->offset) + dev_size -= (params->offset * SECTOR_SIZE); + if (dev_size % sector_size) { + log_err(cd, _("Device size is not aligned to requested sector size.")); + return -EINVAL; + } + } + if (!(cd->type = strdup(CRYPT_PLAIN))) return -ENOMEM; @@ -1472,6 +1482,7 @@ static int _crypt_format_luks2(struct crypt_device *cd, unsigned long alignment_offset = 0; unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE; const char *integrity = params ? params->integrity : NULL; + uint64_t dev_size; cd->u.luks2.hdr.jobj = NULL; @@ -1578,6 +1589,15 @@ static int _crypt_format_luks2(struct crypt_device *cd, if (r < 0) goto out; + if (!integrity && sector_size > SECTOR_SIZE && !device_size(crypt_data_device(cd), &dev_size)) { + dev_size -= (crypt_get_data_offset(cd) * SECTOR_SIZE); + if (dev_size % sector_size) { + log_err(cd, _("Device size is not aligned to requested sector size.")); + r = -EINVAL; + goto out; + } + } + if (params && (params->label || params->subsystem)) { r = LUKS2_hdr_labels(cd, &cd->u.luks2.hdr, params->label, params->subsystem, 0); diff --git a/tests/align-test b/tests/align-test index 3b1eacbb..e802c85b 100755 --- a/tests/align-test +++ b/tests/align-test @@ -3,6 +3,7 @@ CRYPTSETUP="../cryptsetup" DEV="" DEV_STACKED="luks0xbabe" +DEV_NAME="dummyalign" MNT_DIR="./mnt_luks" PWD1="93R4P4pIqAH8" PWD2="mymJeD8ivEhE" @@ -15,6 +16,7 @@ cleanup() { rmdir $MNT_DIR 2>/dev/null fi [ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1 + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 # FIXME scsi_debug sometimes in-use here sleep 1 rmmod scsi_debug 2>/dev/null @@ -59,12 +61,16 @@ format() # key_bits expected [forced] { if [ -z "$3" ] ; then echo -n "Formatting using topology info ($1 bits key)..." - echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c aes-cbc-essiv:sha256 -s $1 + echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c aes-cbc-essiv:sha256 -s $1 || fail else echo -n "Formatting using forced sector alignment $3 ($1 bits key)..." - echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -s $1 -c aes-cbc-essiv:sha256 --align-payload=$3 + echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -s $1 -c aes-cbc-essiv:sha256 --align-payload=$3 ||fail fi + # check the device can be activated + echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + ALIGN=$($CRYPTSETUP luksDump $DEV |grep "Payload offset" | sed -e s/.*\\t//) #echo "ALIGN = $ALIGN" @@ -90,12 +96,16 @@ format_null() { if [ $3 -eq 0 ] ; then echo -n "Formatting using topology info ($1 bits key) [slot 0" - echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 + echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 || fail else echo -n "Formatting using forced sector alignment $3 ($1 bits key) [slot 0" - echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 --align-payload=$3 + echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 --align-payload=$3 || fail fi + # check the device can be activated + echo | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + POFF=$(get_offsets "Payload offset") [ -z "$POFF" ] && fail [ $POFF != $2 ] && fail "Expected data offset differs: expected $2 != detected $POFF" @@ -114,6 +124,21 @@ format_null() echo "]...PASSED" } +format_plain() # sector size +{ + echo -n "Formatting plain device (sector size $1)..." + echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + echo "PASSED" +} + +format_plain_fail() # sector size +{ + echo -n "Formatting plain device (sector size $1, must fail)..." + echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME >/dev/null 2>&1 && fail + echo "PASSED" +} + if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 @@ -175,6 +200,26 @@ format 128 1032 8 format 128 8192 8192 cleanup +echo "# Create classic 512B drive and stack dm-linear (plain mode)" +add_device dev_size_mb=16 sector_size=512 num_tgts=1 +DEV2=$DEV +DEV=/dev/mapper/$DEV_STACKED +dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0" +format_plain 512 +format_plain 1024 +format_plain 2048 +format_plain 4096 +format_plain_fail 1111 +format_plain_fail 8192 +echo "# Create classic 512B drive, unaligned to 4096 and stack dm-linear (plain mode)" +dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1 +dmsetup create $DEV_STACKED --table "0 32762 linear $DEV2 0" +format_plain 512 +format_plain 1024 +format_plain_fail 2048 +format_plain_fail 4096 +cleanup + echo "# Offset check: 512B sector drive" add_device dev_size_mb=16 sector_size=512 num_tgts=1 # |k| expO reqO expected slot offsets diff --git a/tests/align-test2 b/tests/align-test2 index 38506100..bf9f085d 100755 --- a/tests/align-test2 +++ b/tests/align-test2 @@ -3,6 +3,7 @@ CRYPTSETUP="../cryptsetup" DEV="" DEV_STACKED="luks0xbabe" +DEV_NAME="dummyalign" MNT_DIR="./mnt_luks" PWD1="93R4P4pIqAH8" PWD2="mymJeD8ivEhE" @@ -17,6 +18,7 @@ cleanup() { rmdir $MNT_DIR 2>/dev/null fi [ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1 + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 # FIXME scsi_debug sometimes in-use here sleep 1 rmmod scsi_debug 2>/dev/null @@ -81,6 +83,10 @@ format() # expected [forced] [encryption_sector_size] echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size || fail fi + # check the device can be activated + echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + ALIGN=$($CRYPTSETUP luksDump $DEV | tee /tmp/last_dump | grep -A1 "0: crypt" | grep "offset:" | cut -d ' ' -f2) # echo "ALIGN = $ALIGN" @@ -98,6 +104,32 @@ format() # expected [forced] [encryption_sector_size] echo "PASSED" } +format_fail() # expected [forced] [encryption_sector_size] +{ + local _sec_size=512 + + local _exp=$1 + + if [ "${2:0:1}" = "s" ]; then + _sec_size=${2:1} + shift + fi + + test "${3:0:1}" = "s" && _sec_size=${3:1} + + test $_sec_size -eq 512 || local _smsg=" (encryption sector size $_sec_size)" + + if [ -z "$2" ] ; then + echo -n "Formatting using topology info$_smsg (must fail)..." + echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size >/dev/null 2>&1 && fail + else + echo -n "Formatting using forced sector alignment $2$_smsg (must fail)..." + echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size >/dev/null 2>&1 && fail + fi + + echo "PASSED" +} + if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 @@ -122,9 +154,9 @@ format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048 @@ -147,9 +179,9 @@ format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048 @@ -160,9 +192,9 @@ echo "# Create desktop-class 4K drive w/ 1-sector shift (original bug report)" echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=512)" add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=1 num_tgts=1 format $((EXPCT+1)) -format $((EXPCT+1)) s1024 -format $((EXPCT+1)) s2048 -format $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) s4096 format $EXPCT 1 format $EXPCT 1 s1024 format $EXPCT 1 s2048 @@ -172,9 +204,9 @@ format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048 @@ -185,9 +217,9 @@ echo "# Create desktop-class 4K drive w/ 63-sector DOS partition compensation" echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=3584)" add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=7 num_tgts=1 format $((EXPCT+7)) -format $((EXPCT+7)) s1024 -format $((EXPCT+7)) s2048 -format $((EXPCT+7)) s4096 +format_fail $((EXPCT+7)) s1024 +format_fail $((EXPCT+7)) s2048 +format_fail $((EXPCT+7)) s4096 format $EXPCT 1 format $EXPCT 1 s1024 format $EXPCT 1 s2048 @@ -197,9 +229,9 @@ format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048 @@ -221,10 +253,11 @@ format $EXPCT 8 format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 -format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +#FIXME: kernel limits issue? +##format $((EXPCT+1)) $((EXPCT+1)) +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048 @@ -250,9 +283,9 @@ format $EXPCT 8 s1024 format $EXPCT 8 s2048 format $EXPCT 8 s4096 format $((EXPCT+1)) $((EXPCT+1)) -format $((EXPCT+1)) $((EXPCT+1)) s1024 -format $((EXPCT+1)) $((EXPCT+1)) s2048 -format $((EXPCT+1)) $((EXPCT+1)) s4096 +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 format $EXPCT $EXPCT format $EXPCT $EXPCT s1024 format $EXPCT $EXPCT s2048