mirror of https://github.com/encounter/SDL.git
cpuinfo: Check for overflow in SIMD allocation
If the size to be allocated is very large and untrusted, then adding the padding etc. might be enough to cause unsigned overflow, after which a very small amount of memory will be allocated. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
cf1daafa3f
commit
2a7948016a
|
@ -1059,9 +1059,17 @@ SDL_SIMDAlloc(const size_t len)
|
||||||
{
|
{
|
||||||
const size_t alignment = SDL_SIMDGetAlignment();
|
const size_t alignment = SDL_SIMDGetAlignment();
|
||||||
const size_t padding = (alignment - (len % alignment)) % alignment;
|
const size_t padding = (alignment - (len % alignment)) % alignment;
|
||||||
const size_t padded = len + padding;
|
|
||||||
Uint8 *retval = NULL;
|
Uint8 *retval = NULL;
|
||||||
Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
|
Uint8 *ptr;
|
||||||
|
size_t to_allocate;
|
||||||
|
|
||||||
|
/* alignment + padding + sizeof (void *) is bounded (a few hundred
|
||||||
|
* bytes max), so no need to check for overflow within that argument */
|
||||||
|
if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (Uint8 *) SDL_malloc(to_allocate);
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
/* store the actual allocated pointer right before our aligned pointer. */
|
/* store the actual allocated pointer right before our aligned pointer. */
|
||||||
retval = ptr + sizeof (void *);
|
retval = ptr + sizeof (void *);
|
||||||
|
@ -1076,11 +1084,17 @@ SDL_SIMDRealloc(void *mem, const size_t len)
|
||||||
{
|
{
|
||||||
const size_t alignment = SDL_SIMDGetAlignment();
|
const size_t alignment = SDL_SIMDGetAlignment();
|
||||||
const size_t padding = (alignment - (len % alignment)) % alignment;
|
const size_t padding = (alignment - (len % alignment)) % alignment;
|
||||||
const size_t padded = len + padding;
|
|
||||||
Uint8 *retval = (Uint8*) mem;
|
Uint8 *retval = (Uint8*) mem;
|
||||||
void *oldmem = mem;
|
void *oldmem = mem;
|
||||||
size_t memdiff = 0, ptrdiff;
|
size_t memdiff = 0, ptrdiff;
|
||||||
Uint8 *ptr;
|
Uint8 *ptr;
|
||||||
|
size_t to_allocate;
|
||||||
|
|
||||||
|
/* alignment + padding + sizeof (void *) is bounded (a few hundred
|
||||||
|
* bytes max), so no need to check for overflow within that argument */
|
||||||
|
if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (mem) {
|
if (mem) {
|
||||||
void **realptr = (void **) mem;
|
void **realptr = (void **) mem;
|
||||||
|
@ -1091,7 +1105,7 @@ SDL_SIMDRealloc(void *mem, const size_t len)
|
||||||
memdiff = ((size_t) oldmem) - ((size_t) mem);
|
memdiff = ((size_t) oldmem) - ((size_t) mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
|
ptr = (Uint8 *) SDL_realloc(mem, to_allocate);
|
||||||
|
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
return NULL; /* Out of memory, bail! */
|
return NULL; /* Out of memory, bail! */
|
||||||
|
|
Loading…
Reference in New Issue