From a0587d4307f61785be1a5464323d786df51af1b8 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 2 Jul 2016 20:17:25 +0200 Subject: [PATCH 1/2] 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; From 23ce9aa47e2acfdadc04cf649d1e46cdb194c494 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sat, 2 Jul 2016 21:01:25 +0200 Subject: [PATCH 2/2] Fix crypt_generate_volume_key to use size_t for keylength. --- lib/internal.h | 2 +- lib/volumekey.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal.h b/lib/internal.h index aee5f27c..1f4dab59 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -58,7 +58,7 @@ struct volume_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); +struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength); void crypt_free_volume_key(struct volume_key *vk); /* Device backend */ diff --git a/lib/volumekey.c b/lib/volumekey.c index 8b442c44..1ecd29d0 100644 --- a/lib/volumekey.c +++ b/lib/volumekey.c @@ -54,7 +54,7 @@ void crypt_free_volume_key(struct volume_key *vk) } } -struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength) +struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength) { int r; struct volume_key *vk;