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:
parent
c191ff129c
commit
81609be052
33
memory.c
33
memory.c
@ -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);
|
||||||
|
10
puttymem.h
10
puttymem.h
@ -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))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user