mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
All stable@ fixes:
- Fix DM thinp btree corruption seen when inserting a new key/value pair into a full root node. - Fix DM thinp btree removal deadlock due to artificially low number of allowed concurrent locks allowed. - Fix possible DM crypt corruption if kernel keyring service is used. Only affects ciphers using following IVs: essiv, lmk and tcw. - Two DM crypt device initialization error checking fixes. - Fix DM integrity to allow use of async ciphers that require DMA. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJaYmmiAAoJEMUj8QotnQNa55QIANbqG20YBvLhejdIvoOC4npL Lk6PGfAGjftUBocnaua3BMaCCHnPF0DCmVqEZ8Bb07eIUoOygrAbEgJ/o1GjA1Ku 6oLmw+yMls0cu3Qk0aOF/5Z/TYl/fNgYAH9g7oMy4g4DNeD9nEKdRsz/DF2JTVWH t0AUnmMHFLXP001TBW5k4SnC0jqM6JCwd/dn9rlSW6oE5mNLo22+A0vPdpW2tVNW odP2mXAlLQUDTrn9wtAKp7yBJKqbIO56Odv2hQ48VOBjSTB/GMue5OY2tibfS2ci /qo4OzVwzBDAB+bU8MN6AP6MqimvyPUeCeyH20X8Zzbmsd2Mwz+qd+WOsHrNiNg= =R3/E -----END PGP SIGNATURE----- Merge tag 'for-4.15/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm Pull device mapper fixes from Mike Snitzer: "All fixes marked for stable: - Fix DM thinp btree corruption seen when inserting a new key/value pair into a full root node. - Fix DM thinp btree removal deadlock due to artificially low number of allowed concurrent locks allowed. - Fix possible DM crypt corruption if kernel keyring service is used. Only affects ciphers using following IVs: essiv, lmk and tcw. - Two DM crypt device initialization error checking fixes. - Fix DM integrity to allow use of async ciphers that require DMA" * tag 'for-4.15/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm crypt: fix error return code in crypt_ctr() dm crypt: wipe kernel key copy after IV initialization dm integrity: don't store cipher request on the stack dm crypt: fix crash by adding missing check for auth key size dm btree: fix serious bug in btree_split_beneath() dm thin metadata: THIN_MAX_CONCURRENT_LOCKS should be 6
This commit is contained in:
commit
1cf55613a6
@ -1954,10 +1954,15 @@ static int crypt_setkey(struct crypt_config *cc)
|
||||
/* Ignore extra keys (which are used for IV etc) */
|
||||
subkey_size = crypt_subkey_size(cc);
|
||||
|
||||
if (crypt_integrity_hmac(cc))
|
||||
if (crypt_integrity_hmac(cc)) {
|
||||
if (subkey_size < cc->key_mac_size)
|
||||
return -EINVAL;
|
||||
|
||||
crypt_copy_authenckey(cc->authenc_key, cc->key,
|
||||
subkey_size - cc->key_mac_size,
|
||||
cc->key_mac_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < cc->tfms_count; i++) {
|
||||
if (crypt_integrity_hmac(cc))
|
||||
r = crypto_aead_setkey(cc->cipher_tfm.tfms_aead[i],
|
||||
@ -2053,9 +2058,6 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string
|
||||
|
||||
ret = crypt_setkey(cc);
|
||||
|
||||
/* wipe the kernel key payload copy in each case */
|
||||
memset(cc->key, 0, cc->key_size * sizeof(u8));
|
||||
|
||||
if (!ret) {
|
||||
set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
|
||||
kzfree(cc->key_string);
|
||||
@ -2523,6 +2525,10 @@ static int crypt_ctr_cipher(struct dm_target *ti, char *cipher_in, char *key)
|
||||
}
|
||||
}
|
||||
|
||||
/* wipe the kernel key payload copy */
|
||||
if (cc->key_string)
|
||||
memset(cc->key, 0, cc->key_size * sizeof(u8));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2740,6 +2746,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
cc->tag_pool_max_sectors * cc->on_disk_tag_size);
|
||||
if (!cc->tag_pool) {
|
||||
ti->error = "Cannot allocate integrity tags mempool";
|
||||
ret = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -2961,6 +2968,9 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
|
||||
return ret;
|
||||
if (cc->iv_gen_ops && cc->iv_gen_ops->init)
|
||||
ret = cc->iv_gen_ops->init(cc);
|
||||
/* wipe the kernel key payload copy */
|
||||
if (cc->key_string)
|
||||
memset(cc->key, 0, cc->key_size * sizeof(u8));
|
||||
return ret;
|
||||
}
|
||||
if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
|
||||
@ -3007,7 +3017,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
|
||||
|
||||
static struct target_type crypt_target = {
|
||||
.name = "crypt",
|
||||
.version = {1, 18, 0},
|
||||
.version = {1, 18, 1},
|
||||
.module = THIS_MODULE,
|
||||
.ctr = crypt_ctr,
|
||||
.dtr = crypt_dtr,
|
||||
|
@ -2559,7 +2559,8 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
int r = 0;
|
||||
unsigned i;
|
||||
__u64 journal_pages, journal_desc_size, journal_tree_size;
|
||||
unsigned char *crypt_data = NULL;
|
||||
unsigned char *crypt_data = NULL, *crypt_iv = NULL;
|
||||
struct skcipher_request *req = NULL;
|
||||
|
||||
ic->commit_ids[0] = cpu_to_le64(0x1111111111111111ULL);
|
||||
ic->commit_ids[1] = cpu_to_le64(0x2222222222222222ULL);
|
||||
@ -2617,9 +2618,20 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
|
||||
if (blocksize == 1) {
|
||||
struct scatterlist *sg;
|
||||
SKCIPHER_REQUEST_ON_STACK(req, ic->journal_crypt);
|
||||
unsigned char iv[ivsize];
|
||||
skcipher_request_set_tfm(req, ic->journal_crypt);
|
||||
|
||||
req = skcipher_request_alloc(ic->journal_crypt, GFP_KERNEL);
|
||||
if (!req) {
|
||||
*error = "Could not allocate crypt request";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
crypt_iv = kmalloc(ivsize, GFP_KERNEL);
|
||||
if (!crypt_iv) {
|
||||
*error = "Could not allocate iv";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ic->journal_xor = dm_integrity_alloc_page_list(ic);
|
||||
if (!ic->journal_xor) {
|
||||
@ -2641,9 +2653,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
sg_set_buf(&sg[i], va, PAGE_SIZE);
|
||||
}
|
||||
sg_set_buf(&sg[i], &ic->commit_ids, sizeof ic->commit_ids);
|
||||
memset(iv, 0x00, ivsize);
|
||||
memset(crypt_iv, 0x00, ivsize);
|
||||
|
||||
skcipher_request_set_crypt(req, sg, sg, PAGE_SIZE * ic->journal_pages + sizeof ic->commit_ids, iv);
|
||||
skcipher_request_set_crypt(req, sg, sg, PAGE_SIZE * ic->journal_pages + sizeof ic->commit_ids, crypt_iv);
|
||||
init_completion(&comp.comp);
|
||||
comp.in_flight = (atomic_t)ATOMIC_INIT(1);
|
||||
if (do_crypt(true, req, &comp))
|
||||
@ -2659,10 +2671,22 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
crypto_free_skcipher(ic->journal_crypt);
|
||||
ic->journal_crypt = NULL;
|
||||
} else {
|
||||
SKCIPHER_REQUEST_ON_STACK(req, ic->journal_crypt);
|
||||
unsigned char iv[ivsize];
|
||||
unsigned crypt_len = roundup(ivsize, blocksize);
|
||||
|
||||
req = skcipher_request_alloc(ic->journal_crypt, GFP_KERNEL);
|
||||
if (!req) {
|
||||
*error = "Could not allocate crypt request";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
crypt_iv = kmalloc(ivsize, GFP_KERNEL);
|
||||
if (!crypt_iv) {
|
||||
*error = "Could not allocate iv";
|
||||
r = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
crypt_data = kmalloc(crypt_len, GFP_KERNEL);
|
||||
if (!crypt_data) {
|
||||
*error = "Unable to allocate crypt data";
|
||||
@ -2670,8 +2694,6 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
skcipher_request_set_tfm(req, ic->journal_crypt);
|
||||
|
||||
ic->journal_scatterlist = dm_integrity_alloc_journal_scatterlist(ic, ic->journal);
|
||||
if (!ic->journal_scatterlist) {
|
||||
*error = "Unable to allocate sg list";
|
||||
@ -2695,12 +2717,12 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
|
||||
struct skcipher_request *section_req;
|
||||
__u32 section_le = cpu_to_le32(i);
|
||||
|
||||
memset(iv, 0x00, ivsize);
|
||||
memset(crypt_iv, 0x00, ivsize);
|
||||
memset(crypt_data, 0x00, crypt_len);
|
||||
memcpy(crypt_data, §ion_le, min((size_t)crypt_len, sizeof(section_le)));
|
||||
|
||||
sg_init_one(&sg, crypt_data, crypt_len);
|
||||
skcipher_request_set_crypt(req, &sg, &sg, crypt_len, iv);
|
||||
skcipher_request_set_crypt(req, &sg, &sg, crypt_len, crypt_iv);
|
||||
init_completion(&comp.comp);
|
||||
comp.in_flight = (atomic_t)ATOMIC_INIT(1);
|
||||
if (do_crypt(true, req, &comp))
|
||||
@ -2758,6 +2780,9 @@ retest_commit_id:
|
||||
}
|
||||
bad:
|
||||
kfree(crypt_data);
|
||||
kfree(crypt_iv);
|
||||
skcipher_request_free(req);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,14 @@
|
||||
#define SECTOR_TO_BLOCK_SHIFT 3
|
||||
|
||||
/*
|
||||
* For btree insert:
|
||||
* 3 for btree insert +
|
||||
* 2 for btree lookup used within space map
|
||||
* For btree remove:
|
||||
* 2 for shadow spine +
|
||||
* 4 for rebalance 3 child node
|
||||
*/
|
||||
#define THIN_MAX_CONCURRENT_LOCKS 5
|
||||
#define THIN_MAX_CONCURRENT_LOCKS 6
|
||||
|
||||
/* This should be plenty */
|
||||
#define SPACE_MAP_ROOT_SIZE 128
|
||||
|
@ -683,23 +683,8 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
|
||||
pn->keys[1] = rn->keys[0];
|
||||
memcpy_disk(value_ptr(pn, 1), &val, sizeof(__le64));
|
||||
|
||||
/*
|
||||
* rejig the spine. This is ugly, since it knows too
|
||||
* much about the spine
|
||||
*/
|
||||
if (s->nodes[0] != new_parent) {
|
||||
unlock_block(s->info, s->nodes[0]);
|
||||
s->nodes[0] = new_parent;
|
||||
}
|
||||
if (key < le64_to_cpu(rn->keys[0])) {
|
||||
unlock_block(s->info, right);
|
||||
s->nodes[1] = left;
|
||||
} else {
|
||||
unlock_block(s->info, left);
|
||||
s->nodes[1] = right;
|
||||
}
|
||||
s->count = 2;
|
||||
|
||||
unlock_block(s->info, left);
|
||||
unlock_block(s->info, right);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user