aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorseyko <seyko2@gmail.com>2015-04-10 15:17:22 +0300
committerseyko <seyko2@gmail.com>2015-04-10 15:17:22 +0300
commit559675b90acec03b67ed3f2cece1940f00e44c49 (patch)
tree3875745ba543b7b8bb8474d9b7910272fcf75b9d /lib
parente92dc595cd10405b3ed14b2663affeb50b47e169 (diff)
downloadtinycc-559675b90acec03b67ed3f2cece1940f00e44c49.tar.gz
tinycc-559675b90acec03b67ed3f2cece1940f00e44c49.tar.bz2
a bounds checking code for the ARCH=x86_64
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/alloca86_64-bt.S60
-rw-r--r--lib/bcheck.c111
3 files changed, 119 insertions, 54 deletions
diff --git a/lib/Makefile b/lib/Makefile
index aa3984b..348cb72 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,7 +44,7 @@ native : TCC = $(TOP)/tcc$(EXESUF)
cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
-X86_64_O = libtcc1.o alloca86_64.o
+X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BCHECK_O)
ARM_O = libtcc1.o armeabi.o alloca-arm.o
WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
diff --git a/lib/alloca86_64-bt.S b/lib/alloca86_64-bt.S
new file mode 100644
index 0000000..ab8629d
--- /dev/null
+++ b/lib/alloca86_64-bt.S
@@ -0,0 +1,60 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl __bound_alloca
+__bound_alloca:
+
+#ifdef TCC_TARGET_PE
+ # bound checking is not implemented
+ pop %rdx
+ mov %rcx,%rax
+ add $15,%rax
+ and $-16,%rax
+ jz p3
+
+p1:
+ cmp $4096,%rax
+ jbe p2
+ test %rax,-4096(%rsp)
+ sub $4096,%rsp
+ sub $4096,%rax
+ jmp p1
+p2:
+
+ sub %rax,%rsp
+ mov %rsp,%rax
+ add $32,%rax
+
+p3:
+ push %rdx
+ ret
+#else
+ pop %rdx
+ mov %rdi,%rax
+ movl %rax,%rsi # size, a second parm to the __bound_new_region
+
+ add $15,%rax
+ and $-16,%rax
+ jz p3
+
+
+ sub %rax,%rsp
+ mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
+ mov %rsp,%rax
+
+ push %rdx
+ push %rax
+ call __bound_new_region
+ pop %rax
+ pop %rdx
+
+p3:
+ push %rdx
+ ret
+#endif
+
+/* mark stack as nonexecutable */
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
+/* ---------------------------------------------- */
diff --git a/lib/bcheck.c b/lib/bcheck.c
index 7dcb36e..829e33d 100644
--- a/lib/bcheck.c
+++ b/lib/bcheck.c
@@ -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;
}