mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-15 21:00:05 +01:00
Fix allocation of volume key in LUKS1 open_key.
This function should not return allocated key on error path. Recent patch (suspend/resume) introduced a memory leak because of this.
This commit is contained in:
@@ -962,12 +962,12 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
struct volume_key **vk,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
|
||||
struct volume_key *derived_key;
|
||||
char *AfKey;
|
||||
char *AfKey = NULL;
|
||||
size_t AFEKSize;
|
||||
int r;
|
||||
|
||||
@@ -981,8 +981,13 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
if (!derived_key)
|
||||
return -ENOMEM;
|
||||
|
||||
assert(vk->keylength == hdr->keyBytes);
|
||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!*vk) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
AfKey = crypt_safe_alloc(AFEKSize);
|
||||
if (!AfKey) {
|
||||
r = -ENOMEM;
|
||||
@@ -1008,16 +1013,20 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = AF_merge(ctx, AfKey, vk->key, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
r = AF_merge(ctx, AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_verify_volume_key(hdr, vk);
|
||||
r = LUKS_verify_volume_key(hdr, *vk);
|
||||
|
||||
/* Allow only empty passphrase with null cipher */
|
||||
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
||||
r = -EPERM;
|
||||
out:
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
}
|
||||
crypt_safe_free(AfKey);
|
||||
crypt_free_volume_key(derived_key);
|
||||
return r;
|
||||
@@ -1033,16 +1042,14 @@ int LUKS_open_key_with_hdr(int keyIndex,
|
||||
unsigned int i, tried = 0;
|
||||
int r;
|
||||
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
|
||||
if (keyIndex >= 0) {
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, vk, ctx);
|
||||
return (r < 0) ? r : keyIndex;
|
||||
}
|
||||
|
||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
|
||||
if(r == 0)
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx);
|
||||
if (r == 0)
|
||||
return i;
|
||||
|
||||
/* Do not retry for errors that are no -EPERM or -ENOENT,
|
||||
|
||||
Reference in New Issue
Block a user