a bounds checking code for the ARCH=x86_64

This commit is contained in:
seyko
2015-04-10 15:17:22 +03:00
parent e92dc595cd
commit 559675b90a
8 changed files with 319 additions and 64 deletions

View File

@ -31,6 +31,12 @@
/* #define BOUND_DEBUG */
#ifdef BOUND_DEBUG
#define dprintf(a...) fprintf(a)
#else
#define dprintf(a...)
#endif
/* define so that bound array is static (faster, but use memory if
bound checking not used) */
/* #define BOUND_STATIC */
@ -50,12 +56,12 @@
#define BOUND_T1_BITS 13
#define BOUND_T2_BITS 11
#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS)
#define BOUND_E_BITS (sizeof(size_t))
#define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
#define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
#define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
#define BOUND_E_BITS 4
#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
#define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
@ -64,7 +70,7 @@
/* this pointer is generated when bound check is incorrect */
#define INVALID_POINTER ((void *)(-2))
/* size of an empty region */
#define EMPTY_SIZE 0xffffffff
#define EMPTY_SIZE ((size_t)(-1))
/* size of an invalid region */
#define INVALID_SIZE 0
@ -168,9 +174,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
__bound_init();
#if defined(BOUND_DEBUG)
printf("%s %s: 0x%x %d\n", __FILE__, __FUNCTION__, (int)p, offset);
#endif
dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset);
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e +
@ -197,6 +201,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
size_t addr = (size_t)p; \
BoundEntry *e; \
\
dprintf(stderr, "%s %s: %p %p start\n", __FILE__, __FUNCTION__, p, offset); \
\
__bound_init(); \
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \
e = (BoundEntry *)((char *)e + \
@ -212,6 +218,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); \
return INVALID_POINTER; /* return an invalid pointer */ \
} \
dprintf(stderr, "%s %s: return p+offset = %p\n", __FILE__, __FUNCTION__, p + offset); \
return p + offset; \
}
@ -232,9 +239,8 @@ BOUND_PTR_INDIR(16)
void FASTCALL __bound_local_new(void *p1)
{
size_t addr, size, fp, *p = p1;
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s start p1=%p *p1=%p\n", __FILE__, __FUNCTION__, p, *p);
#endif
dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
GET_CALLER_FP(fp);
for(;;) {
addr = p[0];
@ -245,9 +251,7 @@ void FASTCALL __bound_local_new(void *p1)
p += 2;
__bound_new_region((void *)addr, size);
}
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
}
/* called when leaving a function to delete all the local regions */
@ -268,7 +272,7 @@ void FASTCALL __bound_local_delete(void *p1)
static BoundEntry *__bound_new_page(void)
{
BoundEntry *page;
int i;
size_t i;
page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
if (!page)
@ -296,11 +300,11 @@ static void bound_free_entry(BoundEntry *e)
libc_free(e);
}
static inline BoundEntry *get_page(int index)
static BoundEntry *get_page(size_t index)
{
BoundEntry *page;
page = __bound_t1[index];
if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) {
/* create a new page if necessary */
page = __bound_new_page();
__bound_t1[index] = page;
@ -325,7 +329,7 @@ static void mark_invalid(size_t addr, size_t size)
t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
#if 0
printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
#endif
/* first we handle full pages */
@ -364,7 +368,7 @@ static void mark_invalid(size_t addr, size_t size)
void __bound_init(void)
{
int i;
size_t i;
BoundEntry *page;
size_t start, size;
size_t *p;
@ -375,9 +379,7 @@ void __bound_init(void)
inited = 1;
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
/* save malloc hooks and install bound check hooks */
install_malloc_hooks();
@ -445,19 +447,18 @@ void __bound_init(void)
__bound_new_region((void *)p[0], p[1]);
p += 2;
}
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
}
void __bound_main_arg(void **p)
{
void *start = p;
while (*p++);
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, (void *) p - start);
#endif
__bound_new_region(start, (void *) p - start);
}
@ -495,10 +496,8 @@ void __bound_new_region(void *p, size_t size)
__bound_init();
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s(%p, %p) start\n",
dprintf(stderr, "%s, %s(%p, %p) start\n",
__FILE__, __FUNCTION__, p, size);
#endif
start = (size_t)p;
end = start + size;
@ -553,9 +552,8 @@ void __bound_new_region(void *p, size_t size)
}
add_region(e, start, size);
}
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
}
/* delete a region */
@ -610,9 +608,7 @@ int __bound_delete_region(void *p)
__bound_init();
#ifdef BOUND_DEBUG
fprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
start = (size_t)p;
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
@ -681,9 +677,7 @@ int __bound_delete_region(void *p)
delete_region(e, p, empty_size);
}
#ifdef BOUND_DEBUG
fprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
#endif
dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
return 0;
}
@ -771,10 +765,9 @@ void *__bound_malloc(size_t size, const void *caller)
if (!ptr)
return NULL;
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size);
#endif
__bound_new_region(ptr, size);
return ptr;
}
@ -805,10 +798,9 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
if (!ptr)
return NULL;
#ifdef BOUND_DEBUG
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size);
#endif
__bound_new_region(ptr, size);
return ptr;
}
@ -861,23 +853,23 @@ void *__bound_calloc(size_t nmemb, size_t size)
static void bound_dump(void)
{
BoundEntry *page, *e;
int i, j;
size_t i, j;
printf("region dump:\n");
fprintf(stderr, "region dump:\n");
for(i=0;i<BOUND_T1_SIZE;i++) {
page = __bound_t1[i];
for(j=0;j<BOUND_T2_SIZE;j++) {
e = page + j;
/* do not print invalid or empty entries */
if (e->size != EMPTY_SIZE && e->start != 0) {
printf("%08x:",
fprintf(stderr, "%08x:",
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
(j << BOUND_T3_BITS));
do {
printf(" %08lx:%08lx", e->start, e->start + e->size);
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
e = e->next;
} while (e != NULL);
printf("\n");
fprintf(stderr, "\n");
}
}
}
@ -891,19 +883,27 @@ static void __bound_check(const void *p, size_t size)
{
if (size == 0)
return;
p = __bound_ptr_add((void *)p, size);
p = __bound_ptr_add((void *)p, size - 1);
if (p == INVALID_POINTER)
bound_error("invalid pointer");
}
void *__bound_memcpy(void *dst, const void *src, size_t size)
{
void* p;
dprintf(stderr, "%s %s: start, dst=%p src=%p size=%p\n", __FILE__, __FUNCTION__, dst, src, size);
__bound_check(dst, size);
__bound_check(src, size);
/* check also region overlap */
if (src >= dst && src < dst + size)
bound_error("overlapping regions in memcpy()");
return memcpy(dst, src, size);
p = memcpy(dst, src, size);
dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p);
return p;
}
void *__bound_memmove(void *dst, const void *src, size_t size)
@ -939,7 +939,12 @@ int __bound_strlen(const char *s)
char *__bound_strcpy(char *dst, const char *src)
{
int len;
size_t len;
void *p;
dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n", __FILE__, __FUNCTION__, dst, src);
len = __bound_strlen(src);
return __bound_memcpy(dst, src, len + 1);
p = __bound_memcpy(dst, src, len + 1);
dprintf(stderr, "%s %s: strcpy end, p=%p\n", __FILE__, __FUNCTION__, dst, src, p);
return p;
}