From a0587d4307f61785be1a5464323d786df51af1b8 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 2 Jul 2016 20:17:25 +0200 Subject: [PATCH] Avoid integer overflows during memory allocation. It is possible to overflow integers during memory allocation with insanely large "key bytes" specified in a LUKS header. Although it could be argued to properly validate LUKS headers while parsing them, it's still a good idea to fix any form of possible overflow attacks against cryptsetup in these allocation functions. --- lib/internal.h | 2 +- lib/utils_crypt.c | 3 ++- lib/volumekey.c | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/internal.h b/lib/internal.h index b61133bf..aee5f27c 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -57,7 +57,7 @@ struct volume_key { char key[]; }; -struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key); +struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key); struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength); void crypt_free_volume_key(struct volume_key *vk); diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index 76f83257..6f272bc9 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -97,7 +98,7 @@ void *crypt_safe_alloc(size_t size) { struct safe_allocation *alloc; - if (!size) + if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data))) return NULL; alloc = malloc(size + offsetof(struct safe_allocation, data)); diff --git a/lib/volumekey.c b/lib/volumekey.c index e7150aae..8b442c44 100644 --- a/lib/volumekey.c +++ b/lib/volumekey.c @@ -20,14 +20,19 @@ */ #include +#include #include #include "internal.h" -struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key) +struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key) { - struct volume_key *vk = malloc(sizeof(*vk) + keylength); + struct volume_key *vk; + if (!keylength || keylength > (SIZE_MAX - sizeof(*vk))) + return NULL; + + vk = malloc(sizeof(*vk) + keylength); if (!vk) return NULL;