Commit 3a5a1ea0 authored by Milan Broz's avatar Milan Broz

Move safe alloc routines into common lib file.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@351 36d66b0a-2a48-0410-832c-cd162a569da5
parent 6fde2f64
......@@ -61,10 +61,6 @@ int crypt_confirm(struct crypt_device *cd, const char *msg);
void set_error_va(const char *fmt, va_list va);
void set_error(const char *fmt, ...);
const char *get_error(void);
void *safe_alloc(size_t size);
void safe_free(void *data);
void *safe_realloc(void *data, size_t size);
char *safe_strdup(const char *s);
void set_debug_level(int level);
int init_crypto(struct crypt_device *ctx);
......
......@@ -425,7 +425,7 @@ crypt_status_info crypt_status(struct crypt_device *cd, const char *name);
*
* Returns 0 on success or negative errno value otherwise.
*
* @cd - crypt device handle, can be NULL
* @cd - crypt device handle
*/
int crypt_dump(struct crypt_device *cd);
......
......@@ -257,13 +257,13 @@ static char *get_params(const char *device, uint64_t skip, uint64_t offset,
char *params;
char *hexkey;
hexkey = safe_alloc(key_size * 2 + 1);
hexkey = crypt_safe_alloc(key_size * 2 + 1);
if (!hexkey)
return NULL;
hex_key(hexkey, key_size, key);
params = safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64);
params = crypt_safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64);
if (!params)
goto out;
......@@ -271,7 +271,7 @@ static char *get_params(const char *device, uint64_t skip, uint64_t offset,
cipher, hexkey, skip, device, offset);
out:
safe_free(hexkey);
crypt_safe_free(hexkey);
return params;
}
......@@ -516,7 +516,7 @@ out_no_removal:
(void)_dm_udev_wait(cookie);
if (params)
safe_free(params);
crypt_safe_free(params);
if (dmt)
dm_task_destroy(dmt);
......@@ -645,7 +645,7 @@ int dm_query_device(const char *name,
/* key */
if (key_size && key) {
*key = safe_alloc(*key_size);
*key = crypt_safe_alloc(*key_size);
if (!*key) {
r = -ENOMEM;
goto out;
......@@ -656,7 +656,7 @@ int dm_query_device(const char *name,
memcpy(buffer, &key_[i * 2], 2);
(*key)[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) {
safe_free(key);
crypt_safe_free(key);
*key = NULL;
goto out;
}
......@@ -739,7 +739,7 @@ int dm_resume_and_reinstate_key(const char *name,
if (!_dm_crypt_wipe_key_supported)
return -ENOTSUP;
msg = safe_alloc(msg_size);
msg = crypt_safe_alloc(msg_size);
if (!msg)
return -ENOMEM;
......@@ -751,7 +751,7 @@ int dm_resume_and_reinstate_key(const char *name,
!_dm_simple(DM_DEVICE_RESUME, name, 1))
r = -EINVAL;
safe_free(msg);
crypt_safe_free(msg);
return r;
}
......
......@@ -94,7 +94,7 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
const char *key_file, size_t key_size,
const char *pass, size_t passLen)
{
char *key = safe_alloc(key_size);
char *key = crypt_safe_alloc(key_size);
memset(key, 0, key_size);
/* key is coming from binary file */
......@@ -102,7 +102,7 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
if(passLen < key_size) {
log_err(cd, _("Cannot not read %d bytes from key file %s.\n"),
key_size, key_file);
safe_free(key);
crypt_safe_free(key);
return NULL;
}
memcpy(key, pass, key_size);
......@@ -114,7 +114,7 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
if (hash(NULL, hash_name, key, key_size, pass, passLen) < 0) {
log_err(cd, _("Key processing error (using hash algorithm %s).\n"),
hash_name);
safe_free(key);
crypt_safe_free(key);
return NULL;
}
} else if (passLen > key_size) {
......@@ -190,7 +190,7 @@ static int verify_other_keyslot(struct crypt_device *cd,
if (ki == CRYPT_SLOT_ACTIVE)
LUKS_keyslot_set(&cd->hdr, keyIndex, 1);
crypt_free_volume_key(vk);
safe_free(password);
crypt_safe_free(password);
if (openedIndex < 0)
return -EPERM;
......@@ -217,7 +217,7 @@ static int find_keyslot_by_passphrase(struct crypt_device *cd,
keyIndex = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
passwordLen, &cd->hdr, &vk, cd);
crypt_free_volume_key(vk);
safe_free(password);
crypt_safe_free(password);
return keyIndex;
}
......@@ -365,7 +365,7 @@ static int create_device_helper(struct crypt_device *cd,
key_size, processed_key, read_only, reload);
free(dm_cipher);
safe_free(processed_key);
crypt_safe_free(processed_key);
return r;
}
......@@ -425,12 +425,12 @@ static void key_from_terminal(struct crypt_device *cd, char *msg, char **key,
int r, flags = 0;
if (cd->password) {
*key = safe_alloc(MAX_TTY_PASSWORD_LEN);
*key = crypt_safe_alloc(MAX_TTY_PASSWORD_LEN);
if (*key)
return;
r = cd->password(msg, *key, (size_t)key_len, cd->password_usrptr);
if (r < 0) {
safe_free(*key);
crypt_safe_free(*key);
*key = NULL;
} else
*key_len = r;
......@@ -466,7 +466,7 @@ static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslo
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, vk, cd);
safe_free(passphrase_read);
crypt_safe_free(passphrase_read);
passphrase_read = NULL;
} while (r == -EPERM && (--tries > 0));
......@@ -588,7 +588,7 @@ static int crypt_create_and_update_device(struct crypt_options *options, int upd
options->offset, NULL, options->flags & CRYPT_FLAG_READONLY,
options->flags, update);
safe_free(key);
crypt_safe_free(key);
crypt_free(cd);
return r;
}
......@@ -651,7 +651,7 @@ int crypt_resize_device(struct crypt_options *options)
crypt_get_uuid(cd), size, skip, offset,
key_size, key, read_only, 1);
out:
safe_free(key);
crypt_safe_free(key);
free(cipher);
if (options->device == device)
options->device = NULL;
......@@ -760,7 +760,7 @@ int crypt_luksFormat(struct crypt_options *options)
password, passwordLen);
out:
crypt_free(cd);
safe_free(password);
crypt_safe_free(password);
return (r < 0) ? r : 0;
}
......@@ -1375,7 +1375,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
else {
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, &vk, cd);
safe_free(passphrase_read);
crypt_safe_free(passphrase_read);
}
if (r >= 0) {
......@@ -1440,7 +1440,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
passwordLen, &cd->hdr, &vk, cd);
safe_free(password);
crypt_safe_free(password);
}
if(r < 0)
......@@ -1465,7 +1465,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
r = 0;
out:
if (!new_passphrase)
safe_free(new_password);
crypt_safe_free(new_password);
crypt_free_volume_key(vk);
return r ?: keyslot;
}
......@@ -1517,7 +1517,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, passwordLen,
&cd->hdr, &vk, cd);
safe_free(password);
crypt_safe_free(password);
}
if(r < 0)
......@@ -1539,7 +1539,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen,
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
out:
safe_free(new_password);
crypt_safe_free(new_password);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
}
......@@ -1591,7 +1591,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
out:
if (new_password)
safe_free(new_password);
crypt_safe_free(new_password);
crypt_free_volume_key(vk);
return r ?: keyslot;
}
......@@ -1718,7 +1718,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
else {
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, &vk, cd);
safe_free(passphrase_read);
crypt_safe_free(passphrase_read);
}
if (r >= 0) {
......@@ -1844,7 +1844,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
}
memcpy(volume_key, processed_key, key_len);
*volume_key_size = key_len;
safe_free(processed_key);
crypt_safe_free(processed_key);
return 0;
}
......
......@@ -18,11 +18,6 @@
#include "libcryptsetup.h"
#include "internal.h"
struct safe_allocation {
size_t size;
char data[1];
};
static char *error=NULL;
void set_error_va(const char *fmt, va_list va)
......@@ -61,68 +56,6 @@ const char *get_error(void)
return error;
}
void *safe_alloc(size_t size)
{
struct safe_allocation *alloc;
if (!size)
return NULL;
alloc = malloc(size + offsetof(struct safe_allocation, data));
if (!alloc)
return NULL;
alloc->size = size;
return &alloc->data;
}
void safe_free(void *data)
{
struct safe_allocation *alloc;
if (!data)
return;
alloc = data - offsetof(struct safe_allocation, data);
memset(data, 0, alloc->size);
alloc->size = 0x55aa55aa;
free(alloc);
}
void *safe_realloc(void *data, size_t size)
{
void *new_data;
new_data = safe_alloc(size);
if (new_data && data) {
struct safe_allocation *alloc;
alloc = data - offsetof(struct safe_allocation, data);
if (size > alloc->size)
size = alloc->size;
memcpy(new_data, data, size);
}
safe_free(data);
return new_data;
}
char *safe_strdup(const char *s)
{
char *s2 = safe_alloc(strlen(s) + 1);
if (!s2)
return NULL;
return strcpy(s2, s);
}
static int get_alignment(int fd)
{
int alignment = DEFAULT_MEM_ALIGNMENT;
......@@ -423,7 +356,7 @@ void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
if(isatty(fd)) {
int i;
pass = safe_alloc(MAX_TTY_PASSWORD_LEN);
pass = crypt_safe_alloc(MAX_TTY_PASSWORD_LEN);
if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) {
log_err(cd, _("Error reading passphrase from terminal.\n"));
goto out_err;
......@@ -473,7 +406,7 @@ void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
if(i >= buflen - 1) {
buflen += 128;
pass = safe_realloc(pass, buflen);
pass = crypt_safe_realloc(pass, buflen);
if (!pass) {
log_err(cd, _("Out of memory while reading passphrase.\n"));
goto out_err;
......@@ -507,7 +440,7 @@ out_err:
if(fd >= 0 && fd != STDIN_FILENO)
close(fd);
if(pass)
safe_free(pass);
crypt_safe_free(pass);
*key = NULL;
*passLen = 0;
}
......
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include "libcryptsetup.h"
#include "nls.h"
#include "utils_crypt.h"
struct safe_allocation {
size_t size;
char data[0];
};
int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode)
{
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s",
......@@ -18,3 +32,56 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode)
return -EINVAL;
}
/* safe allocations */
void *crypt_safe_alloc(size_t size)
{
struct safe_allocation *alloc;
if (!size)
return NULL;
alloc = malloc(size + offsetof(struct safe_allocation, data));
if (!alloc)
return NULL;
alloc->size = size;
return &alloc->data;
}
void crypt_safe_free(void *data)
{
struct safe_allocation *alloc;
if (!data)
return;
alloc = data - offsetof(struct safe_allocation, data);
memset(data, 0, alloc->size);
alloc->size = 0x55aa55aa;
free(alloc);
}
void *crypt_safe_realloc(void *data, size_t size)
{
void *new_data;
new_data = crypt_safe_alloc(size);
if (new_data && data) {
struct safe_allocation *alloc;
alloc = data - offsetof(struct safe_allocation, data);
if (size > alloc->size)
size = alloc->size;
memcpy(new_data, data, size);
}
crypt_safe_free(data);
return new_data;
}
......@@ -6,4 +6,8 @@
int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode);
void *crypt_safe_alloc(size_t size);
void crypt_safe_free(void *data);
void *crypt_safe_realloc(void *data, size_t size);
#endif /* _UTILS_CRYPT_H */
......@@ -68,7 +68,7 @@ int LUKS_hdr_backup(
return r;
buffer_size = hdr->payloadOffset << SECTOR_SHIFT;
buffer = safe_alloc(buffer_size);
buffer = crypt_safe_alloc(buffer_size);
if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) {
r = -ENOMEM;
goto out;
......@@ -109,7 +109,7 @@ int LUKS_hdr_backup(
out:
if (devfd != -1)
close(devfd);
safe_free(buffer);
crypt_safe_free(buffer);
return r;
}
......@@ -139,7 +139,7 @@ int LUKS_hdr_restore(
goto out;
}
buffer = safe_alloc(buffer_size);
buffer = crypt_safe_alloc(buffer_size);
if (!buffer) {
r = -ENOMEM;
goto out;
......@@ -206,7 +206,7 @@ int LUKS_hdr_restore(
out:
if (devfd != -1)
close(devfd);
safe_free(buffer);
crypt_safe_free(buffer);
return r;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment