Re-add memory bounds checking.

Also fixed a recursive lock error in some configurations, and replaced
a usage of strcpy() with strncpy().
This commit is contained in:
Jordan Bancino 2023-05-29 23:53:17 +00:00
parent a358ca795d
commit bd1918ee05
2 changed files with 58 additions and 23 deletions

View File

@ -50,6 +50,13 @@ struct MemoryInfo
void *pointer; void *pointer;
}; };
#define MEM_BOUND_TYPE UInt32
#define MEM_BOUND 0xDEADBEEF
#define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p)
#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((UInt8 *) p) + x)) + 1)
#define MEM_SIZE_ACTUAL(x) (((x) * sizeof(UInt8)) + (2 * sizeof(MEM_BOUND_TYPE)))
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static void (*hook) (MemoryAction, MemoryInfo *, void *) = NULL; static void (*hook) (MemoryAction, MemoryInfo *, void *) = NULL;
static void *hookArgs = NULL; static void *hookArgs = NULL;
@ -149,12 +156,29 @@ MemoryDelete(MemoryInfo * a)
} }
} }
static int
MemoryCheck(MemoryInfo * a)
{
if (MEM_BOUND_LOWER(a->pointer) != MEM_BOUND ||
MEM_BOUND_UPPER(a->pointer, a->size - (2 * sizeof(MEM_BOUND_TYPE))) != MEM_BOUND)
{
if (hook)
{
hook(MEMORY_CORRUPTED, a, hookArgs);
}
return 0;
}
return 1;
}
void * void *
MemoryAllocate(size_t size, const char *file, int line) MemoryAllocate(size_t size, const char *file, int line)
{ {
void *p; void *p;
MemoryInfo *a; MemoryInfo *a;
MemoryIterate(NULL, NULL);
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
a = malloc(sizeof(MemoryInfo)); a = malloc(sizeof(MemoryInfo));
@ -164,7 +188,7 @@ MemoryAllocate(size_t size, const char *file, int line)
return NULL; return NULL;
} }
p = malloc(size); p = malloc(MEM_SIZE_ACTUAL(size));
if (!p) if (!p)
{ {
free(a); free(a);
@ -172,9 +196,11 @@ MemoryAllocate(size_t size, const char *file, int line)
return NULL; return NULL;
} }
memset(p, 0, size); memset(p, 0, MEM_SIZE_ACTUAL(size));
MEM_BOUND_LOWER(p) = MEM_BOUND;
MEM_BOUND_UPPER(p, size) = MEM_BOUND;
a->size = size; a->size = MEM_SIZE_ACTUAL(size);
a->file = file; a->file = file;
a->line = line; a->line = line;
a->pointer = p; a->pointer = p;
@ -193,7 +219,7 @@ MemoryAllocate(size_t size, const char *file, int line)
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
return p; return ((MEM_BOUND_TYPE *) p) + 1;
} }
void * void *
@ -202,6 +228,8 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
MemoryInfo *a; MemoryInfo *a;
void *new = NULL; void *new = NULL;
MemoryIterate(NULL, NULL);
if (!p) if (!p)
{ {
return MemoryAllocate(size, file, line); return MemoryAllocate(size, file, line);
@ -211,17 +239,20 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
if (a) if (a)
{ {
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
new = realloc(a->pointer, size); new = realloc(a->pointer, MEM_SIZE_ACTUAL(size));
if (new) if (new)
{ {
MemoryDelete(a); MemoryDelete(a);
a->size = size; a->size = MEM_SIZE_ACTUAL(size);
a->file = file; a->file = file;
a->line = line; a->line = line;
a->pointer = new; a->pointer = new;
MemoryInsert(a); MemoryInsert(a);
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
MEM_BOUND_UPPER(a->pointer, size) = MEM_BOUND;
if (hook) if (hook)
{ {
hook(MEMORY_REALLOCATE, a, hookArgs); hook(MEMORY_REALLOCATE, a, hookArgs);
@ -244,7 +275,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
} }
} }
return new; return ((MEM_BOUND_TYPE *) new) + 1;
} }
void void
@ -252,6 +283,8 @@ MemoryFree(void *p, const char *file, int line)
{ {
MemoryInfo *a; MemoryInfo *a;
MemoryIterate(NULL, NULL);
if (!p) if (!p)
{ {
return; return;
@ -340,6 +373,7 @@ MemoryInfoGet(void *p)
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
p = ((MEM_BOUND_TYPE *) p) - 1;
hash = MemoryHash(p); hash = MemoryHash(p);
count = 0; count = 0;
@ -352,6 +386,7 @@ MemoryInfoGet(void *p)
} }
else else
{ {
MemoryCheck(allocations[hash]);
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
return allocations[hash]; return allocations[hash];
} }
@ -369,7 +404,7 @@ MemoryInfoGetSize(MemoryInfo * a)
return 0; return 0;
} }
return a->size; return a->size ? a->size - (2 * sizeof(MEM_BOUND_TYPE)) : 0;
} }
const char * const char *
@ -402,7 +437,7 @@ MemoryInfoGetPointer(MemoryInfo * a)
return NULL; return NULL;
} }
return a->pointer; return ((MEM_BOUND_TYPE *) a->pointer) + 1;
} }
void void
@ -416,6 +451,7 @@ void
{ {
if (allocations[i]) if (allocations[i])
{ {
MemoryCheck(allocations[i]);
if (iterFunc) if (iterFunc)
{ {
iterFunc(allocations[i], args); iterFunc(allocations[i], args);
@ -471,28 +507,27 @@ MemoryDefaultHook(MemoryAction a, MemoryInfo * i, void *args)
switch (a) switch (a)
{ {
case MEMORY_BAD_POINTER: case MEMORY_BAD_POINTER:
write(STDOUT_FILENO, "Bad pointer: 0x", 15); write(STDERR_FILENO, "Bad pointer: 0x", 15);
break; break;
case MEMORY_CORRUPTED: case MEMORY_CORRUPTED:
write(STDOUT_FILENO, "Corrupted block: 0x", 19); write(STDERR_FILENO, "Corrupted block: 0x", 19);
break; break;
default: default:
return; return;
} }
write(STDOUT_FILENO, buf, len); write(STDERR_FILENO, buf, len);
write(STDOUT_FILENO, " to 0x", 6); write(STDERR_FILENO, " to 0x", 6);
len = HexPtr(MemoryInfoGetSize(i), buf, sizeof(buf)); len = HexPtr(MemoryInfoGetSize(i), buf, sizeof(buf));
write(STDOUT_FILENO, buf, len); write(STDERR_FILENO, buf, len);
write(STDOUT_FILENO, " bytes at ", 10); write(STDERR_FILENO, " bytes at ", 10);
write(STDOUT_FILENO, MemoryInfoGetFile(i), strlen(MemoryInfoGetFile(i))); write(STDERR_FILENO, MemoryInfoGetFile(i), strlen(MemoryInfoGetFile(i)));
write(STDOUT_FILENO, ":0x", 3); write(STDERR_FILENO, ":0x", 3);
len = HexPtr(MemoryInfoGetLine(i), buf, sizeof(buf)); len = HexPtr(MemoryInfoGetLine(i), buf, sizeof(buf));
write(STDOUT_FILENO, buf, len); write(STDERR_FILENO, buf, len);
write(STDOUT_FILENO, "\n", 1); write(STDERR_FILENO, "\n", 1);
#if 0
raise(SIGSEGV); raise(SIGSEGV);
#endif
} }
void void

View File

@ -248,7 +248,7 @@ UtilGetLine(char **linePtr, size_t * n, Stream * stream)
static void static void
ThreadNoDestructor(void *p) ThreadNoDestructor(void *p)
{ {
Free(p); free(p);
} }
unsigned long unsigned long
@ -269,7 +269,7 @@ UtilThreadNo(void)
no = pthread_getspecific(key); no = pthread_getspecific(key);
if (!no) if (!no)
{ {
no = Malloc(sizeof(unsigned long)); no = malloc(sizeof(unsigned long));
*no = count++; *no = count++;
pthread_setspecific(key, no); pthread_setspecific(key, no);
} }