Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix integer overflows and harden memory allocator.
  • Loading branch information
EricSesterhennX41 authored and verdammelt committed Feb 23, 2017
1 parent 99c7015 commit c504468
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 21 deletions.
55 changes: 39 additions & 16 deletions src/alloc.c
Expand Up @@ -40,14 +40,23 @@ get_alloc_limit()
return alloc_limit;
}

size_t
check_mul_overflow(size_t a, size_t b, size_t* res)
{
size_t tmp = a * b;
if (a != 0 && tmp / a != b) return 1;
*res = tmp;
return 0;
}

static void
alloc_limit_failure (char *fn_name, size_t size)
{
fprintf (stderr,
fprintf (stderr,
"%s: Maximum allocation size exceeded "
"(maxsize = %lu; size = %lu).\n",
fn_name,
(unsigned long)alloc_limit,
(unsigned long)alloc_limit,
(unsigned long)size);
}

Expand All @@ -56,17 +65,21 @@ alloc_limit_assert (char *fn_name, size_t size)
{
if (alloc_limit && size > alloc_limit)
{
alloc_limit_failure (fn_name, size);
exit (-1);
alloc_limit_failure (fn_name, size);
exit (-1);
}
}

/* attempts to malloc memory, if fails print error and call abort */
void*
xmalloc (size_t size)
xmalloc (size_t num, size_t size)
{
void *ptr = malloc (size);
if (!ptr
size_t res;
if (check_mul_overflow(num, size, &res))
abort();

void *ptr = malloc (res);
if (!ptr
&& (size != 0)) /* some libc don't like size == 0 */
{
perror ("xmalloc: Memory allocation failure");
Expand All @@ -77,20 +90,29 @@ xmalloc (size_t size)

/* Allocates memory but only up to a limit */
void*
checked_xmalloc (size_t size)
checked_xmalloc (size_t num, size_t size)
{
alloc_limit_assert ("checked_xmalloc", size);
return xmalloc (size);
size_t res;
if (check_mul_overflow(num, size, &res))
abort();

alloc_limit_assert ("checked_xmalloc", res);
return xmalloc (num, size);
}

/* xmallocs memory and clears it out */
void*
xcalloc (size_t num, size_t size)
{
void *ptr = malloc(num * size);
size_t res;
if (check_mul_overflow(num, size, &res))
abort();

void *ptr;
ptr = malloc(res);
if (ptr)
{
memset (ptr, '\0', (num * size));
memset (ptr, '\0', (res));
}
return ptr;
}
Expand All @@ -99,9 +121,10 @@ xcalloc (size_t num, size_t size)
void*
checked_xcalloc (size_t num, size_t size)
{
alloc_limit_assert ("checked_xcalloc", (num *size));
size_t res;
if (check_mul_overflow(num, size, &res))
abort();

alloc_limit_assert ("checked_xcalloc", (res));
return xcalloc (num, size);
}



10 changes: 5 additions & 5 deletions src/alloc.h
Expand Up @@ -35,20 +35,20 @@ extern void free (void*);
extern void set_alloc_limit (size_t size);
extern size_t get_alloc_limit();
extern void alloc_limit_assert (char *fn_name, size_t size);
extern void* checked_xmalloc (size_t size);
extern void* xmalloc (size_t size);
extern void* checked_xmalloc (size_t num, size_t size);
extern void* xmalloc (size_t num, size_t size);
extern void* checked_xcalloc (size_t num, size_t size);
extern void* xcalloc (size_t num, size_t size);

#define XMALLOC(_type,_num) \
((_type*)xmalloc((_num)*sizeof(_type)))
((_type*)xmalloc((_num), sizeof(_type)))
#define XCALLOC(_type,_num) \
((_type*)xcalloc((_num), sizeof (_type)))
#define CHECKED_XMALLOC(_type,_num) \
((_type*)checked_xmalloc((_num)*sizeof(_type)))
((_type*)checked_xmalloc((_num),sizeof(_type)))
#define CHECKED_XCALLOC(_type,_num) \
((_type*)checked_xcalloc((_num),sizeof(_type)))
#define XFREE(_ptr) \
do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)
do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)

#endif /* ALLOC_H */

0 comments on commit c504468

Please sign in to comment.