Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef13c8af authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull device mapper fix from Mike Snitzer:
 "Fix a 3.17-rc1 regression introduced by switching the DM crypt target
  to using per-bio data"

* tag 'dm-3.17-fix' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm crypt: fix access beyond the end of allocated space
parents 522a15db d49ec52f
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -1688,6 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	unsigned int key_size, opt_params;
	unsigned long long tmpll;
	int ret;
	size_t iv_size_padding;
	struct dm_arg_set as;
	const char *opt_string;
	char dummy;
@@ -1724,20 +1725,32 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)

	cc->dmreq_start = sizeof(struct ablkcipher_request);
	cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc));
	cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment());
	cc->dmreq_start += crypto_ablkcipher_alignmask(any_tfm(cc)) &
			   ~(crypto_tfm_ctx_alignment() - 1);
	cc->dmreq_start = ALIGN(cc->dmreq_start, __alignof__(struct dm_crypt_request));

	if (crypto_ablkcipher_alignmask(any_tfm(cc)) < CRYPTO_MINALIGN) {
		/* Allocate the padding exactly */
		iv_size_padding = -(cc->dmreq_start + sizeof(struct dm_crypt_request))
				& crypto_ablkcipher_alignmask(any_tfm(cc));
	} else {
		/*
		 * If the cipher requires greater alignment than kmalloc
		 * alignment, we don't know the exact position of the
		 * initialization vector. We must assume worst case.
		 */
		iv_size_padding = crypto_ablkcipher_alignmask(any_tfm(cc));
	}

	cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start +
			sizeof(struct dm_crypt_request) + cc->iv_size);
			sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size);
	if (!cc->req_pool) {
		ti->error = "Cannot allocate crypt request mempool";
		goto bad;
	}

	cc->per_bio_data_size = ti->per_bio_data_size =
				sizeof(struct dm_crypt_io) + cc->dmreq_start +
				sizeof(struct dm_crypt_request) + cc->iv_size;
		ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start +
		      sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size,
		      ARCH_KMALLOC_MINALIGN);

	cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
	if (!cc->page_pool) {