Skip to content

Commit

Permalink
[Pal/LibOS] Fix overflow checks in calloc()
Browse files Browse the repository at this point in the history
- Fixes a bug in PAL's calloc() (missing overflow check, most likely a
  security issue).
- Changes LibOS's calloc() to use overflow builtins for better
  performance (no division needed; we use GCC/clang builtins everywhere
  anyways).

Signed-off-by: Michał Kowalczyk <mkow@invisiblethingslab.com>
  • Loading branch information
mkow committed Feb 2, 2022
1 parent e7429e1 commit 97704a5
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 10 deletions.
8 changes: 4 additions & 4 deletions LibOS/shim/src/shim_malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ void* malloc(size_t size) {
return mem;
}

void* calloc(size_t nmemb, size_t size) {
// This overflow checking is not a UB, because the operands are unsigned.
size_t total = nmemb * size;
if (total / size != nmemb)
void* calloc(size_t num, size_t size) {
size_t total;
if (__builtin_mul_overflow(num, size, &total))
return NULL;

void* ptr = malloc(total);
if (ptr)
memset(ptr, 0, total);
Expand Down
2 changes: 1 addition & 1 deletion Pal/include/pal_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ int _DkSetProtectedFilesKey(const char* pf_key_hex);
void init_slab_mgr(char* mem_pool, size_t mem_pool_size);
void* malloc(size_t size);
void* malloc_copy(const void* mem, size_t size);
void* calloc(size_t nmem, size_t size);
void* calloc(size_t num, size_t size);
void free(void* mem);

#ifdef __GNUC__
Expand Down
10 changes: 6 additions & 4 deletions Pal/src/slab.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,14 @@ void* malloc_copy(const void* mem, size_t size) {
return nmem;
}

void* calloc(size_t nmem, size_t size) {
void* ptr = malloc(nmem * size);
void* calloc(size_t num, size_t size) {
size_t total;
if (__builtin_mul_overflow(num, size, &total))
return NULL;

void* ptr = malloc(total);
if (ptr)
memset(ptr, 0, nmem * size);

memset(ptr, 0, total);
return ptr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#include <limits.h>
#include <stddef.h>

void* calloc(size_t nmem, size_t size);
void* calloc(size_t num, size_t size);
void free(void*);

#define MBEDTLS_PLATFORM_STD_CALLOC calloc
Expand Down

0 comments on commit 97704a5

Please sign in to comment.