1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

Check for overflow in the addition in snew_plus().

We were carefully checking for overflow inside safemalloc() before
multiplying together the two factors of the desired allocation size.
But snew_plus() did an addition _outside_ safemalloc, without the same
guard. Now that addition also happens inside safemalloc.
This commit is contained in:
Simon Tatham 2019-06-28 19:38:45 +01:00
parent c191ff129c
commit 81609be052
2 changed files with 26 additions and 17 deletions

View File

@ -10,26 +10,35 @@
#include "puttymem.h" #include "puttymem.h"
#include "misc.h" #include "misc.h"
void *safemalloc(size_t n, size_t size) void *safemalloc(size_t factor1, size_t factor2, size_t addend)
{ {
void *p; if (factor1 > SIZE_MAX / factor2)
goto fail;
size_t product = factor1 * factor2;
if (n > INT_MAX / size) { if (addend > SIZE_MAX)
p = NULL; goto fail;
} else { if (product > SIZE_MAX - addend)
size *= n; goto fail;
if (size == 0) size = 1; size_t size = product + addend;
if (size == 0)
size = 1;
void *p;
#ifdef MINEFIELD #ifdef MINEFIELD
p = minefield_c_malloc(size); p = minefield_c_malloc(size);
#else #else
p = malloc(size); p = malloc(size);
#endif #endif
}
if (!p) if (!p)
out_of_memory(); goto fail;
return p; return p;
fail:
out_of_memory();
} }
void *saferealloc(void *ptr, size_t n, size_t size) void *saferealloc(void *ptr, size_t n, size_t size)
@ -111,7 +120,7 @@ void *safegrowarray(void *ptr, size_t *allocated, size_t eltsize,
size_t newsize = oldsize + increment; size_t newsize = oldsize + increment;
void *toret; void *toret;
if (secret) { if (secret) {
toret = safemalloc(newsize, eltsize); toret = safemalloc(newsize, eltsize, 0);
memcpy(toret, ptr, oldsize * eltsize); memcpy(toret, ptr, oldsize * eltsize);
smemclr(ptr, oldsize * eltsize); smemclr(ptr, oldsize * eltsize);
sfree(ptr); sfree(ptr);

View File

@ -10,13 +10,13 @@
#include "defs.h" #include "defs.h"
#define smalloc(z) safemalloc(z,1) #define smalloc(z) safemalloc(z,1,0)
#define snmalloc safemalloc #define snmalloc safemalloc
#define srealloc(y,z) saferealloc(y,z,1) #define srealloc(y,z) saferealloc(y,z,1)
#define snrealloc saferealloc #define snrealloc saferealloc
#define sfree safefree #define sfree safefree
void *safemalloc(size_t, size_t); void *safemalloc(size_t factor1, size_t factor2, size_t addend);
void *saferealloc(void *, size_t, size_t); void *saferealloc(void *, size_t, size_t);
void safefree(void *); void safefree(void *);
@ -28,8 +28,8 @@ void safefree(void *);
* TYPECHECK to verify that the _input_ pointer is a pointer to the * TYPECHECK to verify that the _input_ pointer is a pointer to the
* correct type. * correct type.
*/ */
#define snew(type) ((type *)snmalloc(1, sizeof(type))) #define snew(type) ((type *)snmalloc(1, sizeof(type), 0))
#define snewn(n, type) ((type *)snmalloc((n), sizeof(type))) #define snewn(n, type) ((type *)snmalloc((n), sizeof(type), 0))
#define sresize(ptr, n, type) TYPECHECK((type *)0 == (ptr), \ #define sresize(ptr, n, type) TYPECHECK((type *)0 == (ptr), \
((type *)snrealloc((ptr), (n), sizeof(type)))) ((type *)snrealloc((ptr), (n), sizeof(type))))
@ -45,7 +45,7 @@ void safefree(void *);
* result to void *, so you can assign it straight to wherever you * result to void *, so you can assign it straight to wherever you
* wanted it. * wanted it.
*/ */
#define snew_plus(type, extra) ((type *)snmalloc(1, sizeof(type) + (extra))) #define snew_plus(type, extra) ((type *)snmalloc(1, sizeof(type), (extra)))
#define snew_plus_get_aux(ptr) ((void *)((ptr) + 1)) #define snew_plus_get_aux(ptr) ((void *)((ptr) + 1))
/* /*