Move safe alloc routines into common lib file.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@351 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
Milan Broz
2010-10-26 22:07:43 +00:00
parent 6fde2f640b
commit 3a5a1ea0e7
8 changed files with 107 additions and 107 deletions

View File

@@ -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_va(const char *fmt, va_list va);
void set_error(const char *fmt, ...); void set_error(const char *fmt, ...);
const char *get_error(void); 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); void set_debug_level(int level);
int init_crypto(struct crypt_device *ctx); int init_crypto(struct crypt_device *ctx);

View File

@@ -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. * 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); int crypt_dump(struct crypt_device *cd);

View File

@@ -257,13 +257,13 @@ static char *get_params(const char *device, uint64_t skip, uint64_t offset,
char *params; char *params;
char *hexkey; char *hexkey;
hexkey = safe_alloc(key_size * 2 + 1); hexkey = crypt_safe_alloc(key_size * 2 + 1);
if (!hexkey) if (!hexkey)
return NULL; return NULL;
hex_key(hexkey, key_size, key); 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) if (!params)
goto out; goto out;
@@ -271,7 +271,7 @@ static char *get_params(const char *device, uint64_t skip, uint64_t offset,
cipher, hexkey, skip, device, offset); cipher, hexkey, skip, device, offset);
out: out:
safe_free(hexkey); crypt_safe_free(hexkey);
return params; return params;
} }
@@ -516,7 +516,7 @@ out_no_removal:
(void)_dm_udev_wait(cookie); (void)_dm_udev_wait(cookie);
if (params) if (params)
safe_free(params); crypt_safe_free(params);
if (dmt) if (dmt)
dm_task_destroy(dmt); dm_task_destroy(dmt);
@@ -645,7 +645,7 @@ int dm_query_device(const char *name,
/* key */ /* key */
if (key_size && key) { if (key_size && key) {
*key = safe_alloc(*key_size); *key = crypt_safe_alloc(*key_size);
if (!*key) { if (!*key) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
@@ -656,7 +656,7 @@ int dm_query_device(const char *name,
memcpy(buffer, &key_[i * 2], 2); memcpy(buffer, &key_[i * 2], 2);
(*key)[i] = strtoul(buffer, &endp, 16); (*key)[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) { if (endp != &buffer[2]) {
safe_free(key); crypt_safe_free(key);
*key = NULL; *key = NULL;
goto out; goto out;
} }
@@ -739,7 +739,7 @@ int dm_resume_and_reinstate_key(const char *name,
if (!_dm_crypt_wipe_key_supported) if (!_dm_crypt_wipe_key_supported)
return -ENOTSUP; return -ENOTSUP;
msg = safe_alloc(msg_size); msg = crypt_safe_alloc(msg_size);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
@@ -751,7 +751,7 @@ int dm_resume_and_reinstate_key(const char *name,
!_dm_simple(DM_DEVICE_RESUME, name, 1)) !_dm_simple(DM_DEVICE_RESUME, name, 1))
r = -EINVAL; r = -EINVAL;
safe_free(msg); crypt_safe_free(msg);
return r; return r;
} }

View File

@@ -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 *key_file, size_t key_size,
const char *pass, size_t passLen) const char *pass, size_t passLen)
{ {
char *key = safe_alloc(key_size); char *key = crypt_safe_alloc(key_size);
memset(key, 0, key_size); memset(key, 0, key_size);
/* key is coming from binary file */ /* 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) { if(passLen < key_size) {
log_err(cd, _("Cannot not read %d bytes from key file %s.\n"), log_err(cd, _("Cannot not read %d bytes from key file %s.\n"),
key_size, key_file); key_size, key_file);
safe_free(key); crypt_safe_free(key);
return NULL; return NULL;
} }
memcpy(key, pass, key_size); 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) { if (hash(NULL, hash_name, key, key_size, pass, passLen) < 0) {
log_err(cd, _("Key processing error (using hash algorithm %s).\n"), log_err(cd, _("Key processing error (using hash algorithm %s).\n"),
hash_name); hash_name);
safe_free(key); crypt_safe_free(key);
return NULL; return NULL;
} }
} else if (passLen > key_size) { } else if (passLen > key_size) {
@@ -190,7 +190,7 @@ static int verify_other_keyslot(struct crypt_device *cd,
if (ki == CRYPT_SLOT_ACTIVE) if (ki == CRYPT_SLOT_ACTIVE)
LUKS_keyslot_set(&cd->hdr, keyIndex, 1); LUKS_keyslot_set(&cd->hdr, keyIndex, 1);
crypt_free_volume_key(vk); crypt_free_volume_key(vk);
safe_free(password); crypt_safe_free(password);
if (openedIndex < 0) if (openedIndex < 0)
return -EPERM; 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, keyIndex = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
passwordLen, &cd->hdr, &vk, cd); passwordLen, &cd->hdr, &vk, cd);
crypt_free_volume_key(vk); crypt_free_volume_key(vk);
safe_free(password); crypt_safe_free(password);
return keyIndex; return keyIndex;
} }
@@ -365,7 +365,7 @@ static int create_device_helper(struct crypt_device *cd,
key_size, processed_key, read_only, reload); key_size, processed_key, read_only, reload);
free(dm_cipher); free(dm_cipher);
safe_free(processed_key); crypt_safe_free(processed_key);
return r; return r;
} }
@@ -425,12 +425,12 @@ static void key_from_terminal(struct crypt_device *cd, char *msg, char **key,
int r, flags = 0; int r, flags = 0;
if (cd->password) { if (cd->password) {
*key = safe_alloc(MAX_TTY_PASSWORD_LEN); *key = crypt_safe_alloc(MAX_TTY_PASSWORD_LEN);
if (*key) if (*key)
return; return;
r = cd->password(msg, *key, (size_t)key_len, cd->password_usrptr); r = cd->password(msg, *key, (size_t)key_len, cd->password_usrptr);
if (r < 0) { if (r < 0) {
safe_free(*key); crypt_safe_free(*key);
*key = NULL; *key = NULL;
} else } else
*key_len = r; *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, r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, vk, cd); passphrase_size_read, &cd->hdr, vk, cd);
safe_free(passphrase_read); crypt_safe_free(passphrase_read);
passphrase_read = NULL; passphrase_read = NULL;
} while (r == -EPERM && (--tries > 0)); } 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->offset, NULL, options->flags & CRYPT_FLAG_READONLY,
options->flags, update); options->flags, update);
safe_free(key); crypt_safe_free(key);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
@@ -651,7 +651,7 @@ int crypt_resize_device(struct crypt_options *options)
crypt_get_uuid(cd), size, skip, offset, crypt_get_uuid(cd), size, skip, offset,
key_size, key, read_only, 1); key_size, key, read_only, 1);
out: out:
safe_free(key); crypt_safe_free(key);
free(cipher); free(cipher);
if (options->device == device) if (options->device == device)
options->device = NULL; options->device = NULL;
@@ -760,7 +760,7 @@ int crypt_luksFormat(struct crypt_options *options)
password, passwordLen); password, passwordLen);
out: out:
crypt_free(cd); crypt_free(cd);
safe_free(password); crypt_safe_free(password);
return (r < 0) ? r : 0; return (r < 0) ? r : 0;
} }
@@ -1375,7 +1375,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
else { else {
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read, r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, &vk, cd); passphrase_size_read, &cd->hdr, &vk, cd);
safe_free(passphrase_read); crypt_safe_free(passphrase_read);
} }
if (r >= 0) { 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, r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
passwordLen, &cd->hdr, &vk, cd); passwordLen, &cd->hdr, &vk, cd);
safe_free(password); crypt_safe_free(password);
} }
if(r < 0) if(r < 0)
@@ -1465,7 +1465,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
r = 0; r = 0;
out: out:
if (!new_passphrase) if (!new_passphrase)
safe_free(new_password); crypt_safe_free(new_password);
crypt_free_volume_key(vk); crypt_free_volume_key(vk);
return r ?: keyslot; 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, r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, passwordLen,
&cd->hdr, &vk, cd); &cd->hdr, &vk, cd);
safe_free(password); crypt_safe_free(password);
} }
if(r < 0) 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, r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen,
&cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); &cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
out: out:
safe_free(new_password); crypt_safe_free(new_password);
crypt_free_volume_key(vk); crypt_free_volume_key(vk);
return r < 0 ? r : keyslot; 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); &cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd);
out: out:
if (new_password) if (new_password)
safe_free(new_password); crypt_safe_free(new_password);
crypt_free_volume_key(vk); crypt_free_volume_key(vk);
return r ?: keyslot; return r ?: keyslot;
} }
@@ -1718,7 +1718,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
else { else {
r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read, r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read,
passphrase_size_read, &cd->hdr, &vk, cd); passphrase_size_read, &cd->hdr, &vk, cd);
safe_free(passphrase_read); crypt_safe_free(passphrase_read);
} }
if (r >= 0) { if (r >= 0) {
@@ -1844,7 +1844,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
} }
memcpy(volume_key, processed_key, key_len); memcpy(volume_key, processed_key, key_len);
*volume_key_size = key_len; *volume_key_size = key_len;
safe_free(processed_key); crypt_safe_free(processed_key);
return 0; return 0;
} }

View File

@@ -18,11 +18,6 @@
#include "libcryptsetup.h" #include "libcryptsetup.h"
#include "internal.h" #include "internal.h"
struct safe_allocation {
size_t size;
char data[1];
};
static char *error=NULL; static char *error=NULL;
void set_error_va(const char *fmt, va_list va) void set_error_va(const char *fmt, va_list va)
@@ -61,68 +56,6 @@ const char *get_error(void)
return error; 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) static int get_alignment(int fd)
{ {
int alignment = DEFAULT_MEM_ALIGNMENT; 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)) { if(isatty(fd)) {
int i; 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))) { if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) {
log_err(cd, _("Error reading passphrase from terminal.\n")); log_err(cd, _("Error reading passphrase from terminal.\n"));
goto out_err; 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++) { for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
if(i >= buflen - 1) { if(i >= buflen - 1) {
buflen += 128; buflen += 128;
pass = safe_realloc(pass, buflen); pass = crypt_safe_realloc(pass, buflen);
if (!pass) { if (!pass) {
log_err(cd, _("Out of memory while reading passphrase.\n")); log_err(cd, _("Out of memory while reading passphrase.\n"));
goto out_err; goto out_err;
@@ -507,7 +440,7 @@ out_err:
if(fd >= 0 && fd != STDIN_FILENO) if(fd >= 0 && fd != STDIN_FILENO)
close(fd); close(fd);
if(pass) if(pass)
safe_free(pass); crypt_safe_free(pass);
*key = NULL; *key = NULL;
*passLen = 0; *passLen = 0;
} }

View File

@@ -1,9 +1,23 @@
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.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" #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) 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", 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; 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;
}

View File

@@ -6,4 +6,8 @@
int crypt_parse_name_and_mode(const char *s, char *cipher, char *cipher_mode); 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 */ #endif /* _UTILS_CRYPT_H */

View File

@@ -68,7 +68,7 @@ int LUKS_hdr_backup(
return r; return r;
buffer_size = hdr->payloadOffset << SECTOR_SHIFT; buffer_size = hdr->payloadOffset << SECTOR_SHIFT;
buffer = safe_alloc(buffer_size); buffer = crypt_safe_alloc(buffer_size);
if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) { if (!buffer || buffer_size < LUKS_ALIGN_KEYSLOTS) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
@@ -109,7 +109,7 @@ int LUKS_hdr_backup(
out: out:
if (devfd != -1) if (devfd != -1)
close(devfd); close(devfd);
safe_free(buffer); crypt_safe_free(buffer);
return r; return r;
} }
@@ -139,7 +139,7 @@ int LUKS_hdr_restore(
goto out; goto out;
} }
buffer = safe_alloc(buffer_size); buffer = crypt_safe_alloc(buffer_size);
if (!buffer) { if (!buffer) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
@@ -206,7 +206,7 @@ int LUKS_hdr_restore(
out: out:
if (devfd != -1) if (devfd != -1)
close(devfd); close(devfd);
safe_free(buffer); crypt_safe_free(buffer);
return r; return r;
} }