summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@tungstengraphics.com>2008-06-09 19:56:52 +0900
committerJosé Fonseca <jrfonseca@tungstengraphics.com>2008-06-10 08:38:31 +0900
commit3531c5284bb8dc772cd97c6be5bf589c160f9ae8 (patch)
tree7c3f6dea9dff226cf6ee3b1b3549ef80e49fb9c7 /src
parent0c5b1a8ffb21f72fcde64a7daa13d5dab5b90425 (diff)
gallium: Detect buffer overflows in the homegrown memory debugger.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/util/p_debug_mem.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c
index 78497c5f6a..51dbd0a710 100644
--- a/src/gallium/auxiliary/util/p_debug_mem.c
+++ b/src/gallium/auxiliary/util/p_debug_mem.c
@@ -75,6 +75,12 @@ struct debug_memory_header
unsigned magic;
};
+struct debug_memory_footer
+{
+ unsigned magic;
+};
+
+
static struct list_head list = { &list, &list };
static unsigned long last_no = 0;
@@ -98,14 +104,24 @@ data_from_header(struct debug_memory_header *hdr)
return NULL;
}
+static INLINE struct debug_memory_footer *
+footer_from_header(struct debug_memory_header *hdr)
+{
+ if(hdr)
+ return (struct debug_memory_footer *)((char *)hdr + sizeof(struct debug_memory_header) + hdr->size);
+ else
+ return NULL;
+}
+
void *
debug_malloc(const char *file, unsigned line, const char *function,
size_t size)
{
struct debug_memory_header *hdr;
+ struct debug_memory_footer *ftr;
- hdr = real_malloc(sizeof(*hdr) + size);
+ hdr = real_malloc(sizeof(*hdr) + size + sizeof(*ftr));
if(!hdr)
return NULL;
@@ -116,6 +132,9 @@ debug_malloc(const char *file, unsigned line, const char *function,
hdr->size = size;
hdr->magic = DEBUG_MEMORY_MAGIC;
+ ftr = footer_from_header(hdr);
+ ftr->magic = DEBUG_MEMORY_MAGIC;
+
LIST_ADDTAIL(&hdr->head, &list);
return data_from_header(hdr);
@@ -126,6 +145,7 @@ debug_free(const char *file, unsigned line, const char *function,
void *ptr)
{
struct debug_memory_header *hdr;
+ struct debug_memory_footer *ftr;
if(!ptr)
return;
@@ -139,8 +159,17 @@ debug_free(const char *file, unsigned line, const char *function,
return;
}
+ ftr = footer_from_header(hdr);
+ if(ftr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s:%u:%s: buffer overflow %p\n",
+ hdr->file, hdr->line, hdr->function,
+ ptr);
+ debug_assert(0);
+ }
+
LIST_DEL(&hdr->head);
hdr->magic = 0;
+ ftr->magic = 0;
real_free(hdr);
}
@@ -160,6 +189,7 @@ debug_realloc(const char *file, unsigned line, const char *function,
void *old_ptr, size_t old_size, size_t new_size )
{
struct debug_memory_header *old_hdr, *new_hdr;
+ struct debug_memory_footer *old_ftr, *new_ftr;
void *new_ptr;
if(!old_ptr)
@@ -179,8 +209,16 @@ debug_realloc(const char *file, unsigned line, const char *function,
return NULL;
}
+ old_ftr = footer_from_header(old_hdr);
+ if(old_ftr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s:%u:%s: buffer overflow %p\n",
+ old_hdr->file, old_hdr->line, old_hdr->function,
+ old_ptr);
+ debug_assert(0);
+ }
+
/* alloc new */
- new_hdr = real_malloc(sizeof(*new_hdr) + new_size);
+ new_hdr = real_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr));
if(!new_hdr)
return NULL;
new_hdr->no = old_hdr->no;
@@ -189,14 +227,19 @@ debug_realloc(const char *file, unsigned line, const char *function,
new_hdr->function = old_hdr->function;
new_hdr->size = new_size;
new_hdr->magic = DEBUG_MEMORY_MAGIC;
- LIST_REPLACE(&old_hdr->head, &new_hdr->head);
+ new_ftr = footer_from_header(new_hdr);
+ new_ftr->magic = DEBUG_MEMORY_MAGIC;
+
+ LIST_REPLACE(&old_hdr->head, &new_hdr->head);
+
/* copy data */
new_ptr = data_from_header(new_hdr);
memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size );
/* free old */
old_hdr->magic = 0;
+ old_ftr->magic = 0;
real_free(old_hdr);
return new_ptr;