mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-16 13:20:11 +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,
|
const char *password,
|
||||||
size_t passwordLen,
|
size_t passwordLen,
|
||||||
struct luks_phdr *hdr,
|
struct luks_phdr *hdr,
|
||||||
struct volume_key *vk,
|
struct volume_key **vk,
|
||||||
struct crypt_device *ctx)
|
struct crypt_device *ctx)
|
||||||
{
|
{
|
||||||
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
|
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
|
||||||
struct volume_key *derived_key;
|
struct volume_key *derived_key;
|
||||||
char *AfKey;
|
char *AfKey = NULL;
|
||||||
size_t AFEKSize;
|
size_t AFEKSize;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -981,8 +981,13 @@ static int LUKS_open_key(unsigned int keyIndex,
|
|||||||
if (!derived_key)
|
if (!derived_key)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
assert(vk->keylength == hdr->keyBytes);
|
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
if (!*vk) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||||
AfKey = crypt_safe_alloc(AFEKSize);
|
AfKey = crypt_safe_alloc(AFEKSize);
|
||||||
if (!AfKey) {
|
if (!AfKey) {
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
@@ -1008,16 +1013,20 @@ static int LUKS_open_key(unsigned int keyIndex,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
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)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = LUKS_verify_volume_key(hdr, vk);
|
r = LUKS_verify_volume_key(hdr, *vk);
|
||||||
|
|
||||||
/* Allow only empty passphrase with null cipher */
|
/* Allow only empty passphrase with null cipher */
|
||||||
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
||||||
r = -EPERM;
|
r = -EPERM;
|
||||||
out:
|
out:
|
||||||
|
if (r < 0) {
|
||||||
|
crypt_free_volume_key(*vk);
|
||||||
|
*vk = NULL;
|
||||||
|
}
|
||||||
crypt_safe_free(AfKey);
|
crypt_safe_free(AfKey);
|
||||||
crypt_free_volume_key(derived_key);
|
crypt_free_volume_key(derived_key);
|
||||||
return r;
|
return r;
|
||||||
@@ -1033,16 +1042,14 @@ int LUKS_open_key_with_hdr(int keyIndex,
|
|||||||
unsigned int i, tried = 0;
|
unsigned int i, tried = 0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
|
||||||
|
|
||||||
if (keyIndex >= 0) {
|
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;
|
return (r < 0) ? r : keyIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||||
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
|
r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx);
|
||||||
if(r == 0)
|
if (r == 0)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
/* Do not retry for errors that are no -EPERM or -ENOENT,
|
/* Do not retry for errors that are no -EPERM or -ENOENT,
|
||||||
|
|||||||
Reference in New Issue
Block a user