diff --git a/lib/internal.h b/lib/internal.h index a06d558d..e960e101 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -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); diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 0db338be..8206164a 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -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); diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index ec83ec1a..7a0dc420 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -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; } diff --git a/lib/setup.c b/lib/setup.c index 6da952f8..22ace1d6 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -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; } diff --git a/lib/utils.c b/lib/utils.c index bbb423c9..8c154ec5 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -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; } diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index d8db4643..e6b2ac54 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -1,9 +1,23 @@ +#include +#include #include #include #include +#include +#include +#include +#include +#include +#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; +} diff --git a/lib/utils_crypt.h b/lib/utils_crypt.h index 10ed36e6..ee8f4cd1 100644 --- a/lib/utils_crypt.h +++ b/lib/utils_crypt.h @@ -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 */ diff --git a/luks/keymanage.c b/luks/keymanage.c index a95de1fc..4fbad0dc 100644 --- a/luks/keymanage.c +++ b/luks/keymanage.c @@ -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; }