mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
dm-crypt: allow encryption sector size up to PAGE_SIZE
The "sector_size:<bytes>" option is capped at 4096 bytes. The reason is stated in commit8f0009a225("dm crypt: optionally support larger encryption sector size"): "the maximal IO must fit into the page limit, so the limit is set to the minimal page size possible (4096 bytes)." The rule is right; only the way it is resolved is not. The page limit it refers to is a property of the kernel that is running, but it was written as the smallest page size of any architecture, so a kernel with larger pages is held to a limit that belongs to a different one. The block layer has since stopped doing that for its own block size, in commit47dd675323("block/bdev: lift block size restrictions to 64k"), and dm-crypt is now the stricter of the two. Apply the same rule to the kernel being built: raise the cap to min(PAGE_SIZE, BLK_MAX_BLOCK_SIZE). PAGE_SIZE is still the page limit the original commit meant. A sector is passed to the crypto API as a single scatterlist entry, bio_iter_iovec() never returns more than PAGE_SIZE bytes, and crypt_alloc_buffer() may fall back to order-0 pages for the write bounce buffer. BLK_MAX_BLOCK_SIZE caps the logical block size that crypt_io_hints() announces. It is PAGE_SIZE without transparent hugepages, and 64K with them, which no architecture having a PAGE_SIZE above 64K can enable - so it does not lower the bound on any configuration today. It is in the expression so that this target cannot announce a block size blk_validate_limits() would reject. A larger unit also turns several crypto requests per page into one. Whether that is worth anything depends on the driver: for a CPU cipher the per-request cost is small, and it only pays off where a request carries a large fixed cost, as when the cipher is offloaded over DMA. Widen sector_size to unsigned int so that it can hold a sector larger than 65535. That also makes the option reject an argument of 69632, which %hu truncates to 4096 and accepts as a 4096-byte sector. Document that an encryption sector larger than the unit the device writes atomically can be torn by a power failure, and what each cipher mode does when that happens. The maximum stays 4096 wherever PAGE_SIZE is 4096, the default stays 512 bytes, and every table using a size from 512 to 4096 behaves as it did. The one behavioural change is the truncation above: an argument that wrapped into range is now rejected rather than silently accepted. A mapping larger than 4096 bytes can only be activated where PAGE_SIZE allows, so it is not suitable for portable on-disk formats. Bump the target version so that userspace can detect the new limit. Assisted-by: LLM Signed-off-by: Itai Handler <itai.handler@gmail.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
This commit is contained in:
parent
17383c7b81
commit
1acc65c30f
|
|
@ -153,9 +153,27 @@ integrity_key_size:<bytes>
|
|||
|
||||
sector_size:<bytes>
|
||||
Use <bytes> as the encryption unit instead of 512 bytes sectors.
|
||||
This option can be in range 512 - 4096 bytes and must be power of two.
|
||||
This option can be in range 512 - PAGE_SIZE bytes, further limited by
|
||||
the block layer's maximum block size, and must be power of two.
|
||||
Virtual device will announce this size as a minimal IO and logical sector.
|
||||
|
||||
An encryption unit larger than 4096 bytes can only be used on a system
|
||||
whose PAGE_SIZE is at least that large, so such a mapping is not
|
||||
portable across architectures and is unsuitable for portable on-disk
|
||||
formats such as LUKS.
|
||||
|
||||
An encryption sector larger than the unit the underlying device writes
|
||||
atomically can be torn by a power failure, leaving part of the sector
|
||||
written and part not. A device that advertises no atomic write unit
|
||||
gives no such guarantee beyond a single logical block, so this is
|
||||
already possible at 4096 bytes; a larger sector widens the window.
|
||||
With XTS and ECB the torn sector decrypts to a mixture of old and new
|
||||
data, as a torn write does on an unencrypted device. With chaining
|
||||
modes the block at the tear also decrypts to garbage, with AEAD the
|
||||
whole sector fails authentication, and with the wide-block diffusers
|
||||
the whole sector decrypts to garbage. Use a large sector only where
|
||||
losing a sector to a power failure is acceptable.
|
||||
|
||||
iv_large_sectors
|
||||
IV generators will use sector number counted in <sector_size> units
|
||||
instead of default 512 bytes sectors.
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ struct crypt_config {
|
|||
} iv_gen_private;
|
||||
u64 iv_offset;
|
||||
unsigned int iv_size;
|
||||
unsigned short sector_size;
|
||||
unsigned int sector_size;
|
||||
unsigned char sector_shift;
|
||||
|
||||
union {
|
||||
|
|
@ -241,6 +241,24 @@ struct crypt_config {
|
|||
#define MAX_TAG_SIZE 480
|
||||
#define POOL_ENTRY_SIZE 512
|
||||
|
||||
/*
|
||||
* Largest encryption sector size that can be requested with the
|
||||
* "sector_size:<bytes>" option.
|
||||
*
|
||||
* A sector is handed to the crypto API as a single scatterlist entry, so it
|
||||
* has to be covered by one bio_vec. bio_iter_iovec() never returns more than
|
||||
* PAGE_SIZE bytes, and crypt_alloc_buffer() may fall back to order-0 pages
|
||||
* for the write bounce buffer, so PAGE_SIZE is the ceiling.
|
||||
*
|
||||
* crypt_io_hints() announces the sector size as the logical block size, which
|
||||
* the block layer caps at BLK_MAX_BLOCK_SIZE. That cap is never below
|
||||
* PAGE_SIZE in any configuration today, so it does not lower the limit; take
|
||||
* the minimum anyway so that this target cannot announce a block size
|
||||
* blk_validate_limits() would reject.
|
||||
*/
|
||||
#define DM_CRYPT_MAX_SECTOR_SIZE MIN_T(unsigned int, PAGE_SIZE, \
|
||||
BLK_MAX_BLOCK_SIZE)
|
||||
|
||||
static DEFINE_SPINLOCK(dm_crypt_clients_lock);
|
||||
static unsigned int dm_crypt_clients_n;
|
||||
static volatile unsigned long dm_crypt_pages_per_client;
|
||||
|
|
@ -3137,9 +3155,9 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar
|
|||
}
|
||||
cc->key_mac_size = val;
|
||||
set_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags);
|
||||
} else if (sscanf(opt_string, "sector_size:%hu%c", &cc->sector_size, &dummy) == 1) {
|
||||
} else if (sscanf(opt_string, "sector_size:%u%c", &cc->sector_size, &dummy) == 1) {
|
||||
if (cc->sector_size < (1 << SECTOR_SHIFT) ||
|
||||
cc->sector_size > 4096 ||
|
||||
cc->sector_size > DM_CRYPT_MAX_SECTOR_SIZE ||
|
||||
(cc->sector_size & (cc->sector_size - 1))) {
|
||||
ti->error = "Invalid feature value for sector_size";
|
||||
return -EINVAL;
|
||||
|
|
@ -3559,7 +3577,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
|
|||
if (cc->used_tag_size)
|
||||
DMEMIT(" integrity:%u:%s", cc->used_tag_size, cc->cipher_auth);
|
||||
if (cc->sector_size != (1 << SECTOR_SHIFT))
|
||||
DMEMIT(" sector_size:%d", cc->sector_size);
|
||||
DMEMIT(" sector_size:%u", cc->sector_size);
|
||||
if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags))
|
||||
DMEMIT(" iv_large_sectors");
|
||||
if (test_bit(CRYPT_KEY_MAC_SIZE_SET, &cc->cipher_flags))
|
||||
|
|
@ -3585,7 +3603,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
|
|||
DMEMIT(",integrity_tag_size=%u,cipher_auth=%s",
|
||||
cc->used_tag_size, cc->cipher_auth);
|
||||
if (cc->sector_size != (1 << SECTOR_SHIFT))
|
||||
DMEMIT(",sector_size=%d", cc->sector_size);
|
||||
DMEMIT(",sector_size=%u", cc->sector_size);
|
||||
if (cc->cipher_string)
|
||||
DMEMIT(",cipher_string=%s", cc->cipher_string);
|
||||
|
||||
|
|
@ -3703,7 +3721,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
|
|||
|
||||
static struct target_type crypt_target = {
|
||||
.name = "crypt",
|
||||
.version = {1, 29, 0},
|
||||
.version = {1, 30, 0},
|
||||
.module = THIS_MODULE,
|
||||
.ctr = crypt_ctr,
|
||||
.dtr = crypt_dtr,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user