Skip to content

Commit c504468

Browse files
EricSesterhennX41verdammelt
authored andcommitted
Fix integer overflows and harden memory allocator.
1 parent 99c7015 commit c504468

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

Diff for: src/alloc.c

+39-16
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,23 @@ get_alloc_limit()
4040
return alloc_limit;
4141
}
4242

43+
size_t
44+
check_mul_overflow(size_t a, size_t b, size_t* res)
45+
{
46+
size_t tmp = a * b;
47+
if (a != 0 && tmp / a != b) return 1;
48+
*res = tmp;
49+
return 0;
50+
}
51+
4352
static void
4453
alloc_limit_failure (char *fn_name, size_t size)
4554
{
46-
fprintf (stderr,
55+
fprintf (stderr,
4756
"%s: Maximum allocation size exceeded "
4857
"(maxsize = %lu; size = %lu).\n",
4958
fn_name,
50-
(unsigned long)alloc_limit,
59+
(unsigned long)alloc_limit,
5160
(unsigned long)size);
5261
}
5362

@@ -56,17 +65,21 @@ alloc_limit_assert (char *fn_name, size_t size)
5665
{
5766
if (alloc_limit && size > alloc_limit)
5867
{
59-
alloc_limit_failure (fn_name, size);
60-
exit (-1);
68+
alloc_limit_failure (fn_name, size);
69+
exit (-1);
6170
}
6271
}
6372

6473
/* attempts to malloc memory, if fails print error and call abort */
6574
void*
66-
xmalloc (size_t size)
75+
xmalloc (size_t num, size_t size)
6776
{
68-
void *ptr = malloc (size);
69-
if (!ptr
77+
size_t res;
78+
if (check_mul_overflow(num, size, &res))
79+
abort();
80+
81+
void *ptr = malloc (res);
82+
if (!ptr
7083
&& (size != 0)) /* some libc don't like size == 0 */
7184
{
7285
perror ("xmalloc: Memory allocation failure");
@@ -77,20 +90,29 @@ xmalloc (size_t size)
7790

7891
/* Allocates memory but only up to a limit */
7992
void*
80-
checked_xmalloc (size_t size)
93+
checked_xmalloc (size_t num, size_t size)
8194
{
82-
alloc_limit_assert ("checked_xmalloc", size);
83-
return xmalloc (size);
95+
size_t res;
96+
if (check_mul_overflow(num, size, &res))
97+
abort();
98+
99+
alloc_limit_assert ("checked_xmalloc", res);
100+
return xmalloc (num, size);
84101
}
85102

86103
/* xmallocs memory and clears it out */
87104
void*
88105
xcalloc (size_t num, size_t size)
89106
{
90-
void *ptr = malloc(num * size);
107+
size_t res;
108+
if (check_mul_overflow(num, size, &res))
109+
abort();
110+
111+
void *ptr;
112+
ptr = malloc(res);
91113
if (ptr)
92114
{
93-
memset (ptr, '\0', (num * size));
115+
memset (ptr, '\0', (res));
94116
}
95117
return ptr;
96118
}
@@ -99,9 +121,10 @@ xcalloc (size_t num, size_t size)
99121
void*
100122
checked_xcalloc (size_t num, size_t size)
101123
{
102-
alloc_limit_assert ("checked_xcalloc", (num *size));
124+
size_t res;
125+
if (check_mul_overflow(num, size, &res))
126+
abort();
127+
128+
alloc_limit_assert ("checked_xcalloc", (res));
103129
return xcalloc (num, size);
104130
}
105-
106-
107-

Diff for: src/alloc.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@ extern void free (void*);
3535
extern void set_alloc_limit (size_t size);
3636
extern size_t get_alloc_limit();
3737
extern void alloc_limit_assert (char *fn_name, size_t size);
38-
extern void* checked_xmalloc (size_t size);
39-
extern void* xmalloc (size_t size);
38+
extern void* checked_xmalloc (size_t num, size_t size);
39+
extern void* xmalloc (size_t num, size_t size);
4040
extern void* checked_xcalloc (size_t num, size_t size);
4141
extern void* xcalloc (size_t num, size_t size);
4242

4343
#define XMALLOC(_type,_num) \
44-
((_type*)xmalloc((_num)*sizeof(_type)))
44+
((_type*)xmalloc((_num), sizeof(_type)))
4545
#define XCALLOC(_type,_num) \
4646
((_type*)xcalloc((_num), sizeof (_type)))
4747
#define CHECKED_XMALLOC(_type,_num) \
48-
((_type*)checked_xmalloc((_num)*sizeof(_type)))
48+
((_type*)checked_xmalloc((_num),sizeof(_type)))
4949
#define CHECKED_XCALLOC(_type,_num) \
5050
((_type*)checked_xcalloc((_num),sizeof(_type)))
5151
#define XFREE(_ptr) \
52-
do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)
52+
do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)
5353

5454
#endif /* ALLOC_H */

0 commit comments

Comments
 (0)