mirror of
https://github.com/frida/tinycc
synced 2024-12-01 11:56:58 +03:00
fix for the bcheck.o (bug #14958)
- care about __attribute__ redefinition in the system headers - an invalid pointer must be returned when (addr >= e->size), and not (addr > e->size) A test program: #include <stdio.h> #include <stdlib.h> int main () { int v[10]; fprintf(stderr, "&v[0] = %p\n", &v[0]); fprintf(stderr, "&v[10] = %p\n", &v[10]); exit(1); return 0; } // tcc -b test.c The output before a patch: &v[0] = 0xbf929d8c &v[10] = 0xbf929db4 The output after a patch: &v[0] = 0xbff6e33c &v[10] = 0xfffffffe
This commit is contained in:
parent
f2cfc07554
commit
d80593bc4d
72
lib/bcheck.c
72
lib/bcheck.c
@ -80,6 +80,10 @@ void __bound_init(void);
|
|||||||
void __bound_new_region(void *p, size_t size);
|
void __bound_new_region(void *p, size_t size);
|
||||||
int __bound_delete_region(void *p);
|
int __bound_delete_region(void *p);
|
||||||
|
|
||||||
|
#ifdef __attribute__
|
||||||
|
/* __attribute__ is redifened in system headers */
|
||||||
|
#undef __attribute__
|
||||||
|
#endif
|
||||||
#define FASTCALL __attribute__((regparm(3)))
|
#define FASTCALL __attribute__((regparm(3)))
|
||||||
|
|
||||||
void *__bound_malloc(size_t size, const void *caller);
|
void *__bound_malloc(size_t size, const void *caller);
|
||||||
@ -161,7 +165,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
|
|||||||
size_t addr = (size_t)p;
|
size_t addr = (size_t)p;
|
||||||
BoundEntry *e;
|
BoundEntry *e;
|
||||||
#if defined(BOUND_DEBUG)
|
#if defined(BOUND_DEBUG)
|
||||||
printf("add: 0x%x %d\n", (int)p, offset);
|
printf("%s %s: 0x%x %d\n", __FILE__, __FUNCTION__, (int)p, offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||||
@ -174,15 +178,19 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
|
|||||||
addr = (size_t)p - e->start;
|
addr = (size_t)p - e->start;
|
||||||
}
|
}
|
||||||
addr += offset;
|
addr += offset;
|
||||||
if (addr > e->size)
|
if (addr >= e->size) {
|
||||||
|
#if defined(BOUND_DEBUG)
|
||||||
|
printf("%s %s: 0x%zx is outside of the region\n", __FILE__, __FUNCTION__, p + offset);
|
||||||
|
#endif
|
||||||
return INVALID_POINTER; /* return an invalid pointer */
|
return INVALID_POINTER; /* return an invalid pointer */
|
||||||
|
}
|
||||||
return p + offset;
|
return p + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return '(p + offset)' for pointer indirection (the resulting must
|
/* return '(p + offset)' for pointer indirection (the resulting must
|
||||||
be strictly inside the region */
|
be strictly inside the region */
|
||||||
#define BOUND_PTR_INDIR(dsize) \
|
#define BOUND_PTR_INDIR(dsize) \
|
||||||
void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \
|
void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
|
||||||
{ \
|
{ \
|
||||||
size_t addr = (size_t)p; \
|
size_t addr = (size_t)p; \
|
||||||
BoundEntry *e; \
|
BoundEntry *e; \
|
||||||
@ -197,7 +205,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \
|
|||||||
addr = (size_t)p - e->start; \
|
addr = (size_t)p - e->start; \
|
||||||
} \
|
} \
|
||||||
addr += offset + dsize; \
|
addr += offset + dsize; \
|
||||||
if (addr > e->size) \
|
if (addr >= e->size) \
|
||||||
return INVALID_POINTER; /* return an invalid pointer */ \
|
return INVALID_POINTER; /* return an invalid pointer */ \
|
||||||
return p + offset; \
|
return p + offset; \
|
||||||
}
|
}
|
||||||
@ -219,6 +227,9 @@ BOUND_PTR_INDIR(16)
|
|||||||
void FASTCALL __bound_local_new(void *p1)
|
void FASTCALL __bound_local_new(void *p1)
|
||||||
{
|
{
|
||||||
size_t addr, size, fp, *p = p1;
|
size_t addr, size, fp, *p = p1;
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s start p1=%zx *p1=%zx\n", __FILE__, __FUNCTION__, p, *p);
|
||||||
|
#endif
|
||||||
GET_CALLER_FP(fp);
|
GET_CALLER_FP(fp);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
addr = p[0];
|
addr = p[0];
|
||||||
@ -229,6 +240,9 @@ void FASTCALL __bound_local_new(void *p1)
|
|||||||
p += 2;
|
p += 2;
|
||||||
__bound_new_region((void *)addr, size);
|
__bound_new_region((void *)addr, size);
|
||||||
}
|
}
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called when leaving a function to delete all the local regions */
|
/* called when leaving a function to delete all the local regions */
|
||||||
@ -348,9 +362,11 @@ void __bound_init(void)
|
|||||||
int i;
|
int i;
|
||||||
BoundEntry *page;
|
BoundEntry *page;
|
||||||
size_t start, size;
|
size_t start, size;
|
||||||
|
size_t *p;
|
||||||
|
|
||||||
/* int *p; */
|
#ifdef BOUND_DEBUG
|
||||||
__PTRDIFF_TYPE__ *p; /* 32 or 64 bit integer */
|
fprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* save malloc hooks and install bound check hooks */
|
/* save malloc hooks and install bound check hooks */
|
||||||
install_malloc_hooks();
|
install_malloc_hooks();
|
||||||
@ -413,17 +429,24 @@ void __bound_init(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* add all static bound check values */
|
/* add all static bound check values */
|
||||||
p = (__PTRDIFF_TYPE__ *)&__bounds_start;
|
p = (size_t *)&__bounds_start;
|
||||||
while (p[0] != 0) {
|
while (p[0] != 0) {
|
||||||
__bound_new_region((void *)p[0], p[1]);
|
__bound_new_region((void *)p[0], p[1]);
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bound_main_arg(void **p)
|
void __bound_main_arg(void **p)
|
||||||
{
|
{
|
||||||
void *start = p;
|
void *start = p;
|
||||||
while (*p++);
|
while (*p++);
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n",
|
||||||
|
__FILE__, __FUNCTION__, (void *) p - start);
|
||||||
|
#endif
|
||||||
__bound_new_region(start, (void *) p - start);
|
__bound_new_region(start, (void *) p - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,6 +482,11 @@ void __bound_new_region(void *p, size_t size)
|
|||||||
BoundEntry *page, *e, *e2;
|
BoundEntry *page, *e, *e2;
|
||||||
size_t t1_start, t1_end, i, t2_start, t2_end;
|
size_t t1_start, t1_end, i, t2_start, t2_end;
|
||||||
|
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s(%p, %zx) start\n",
|
||||||
|
__FILE__, __FUNCTION__, p, size);
|
||||||
|
#endif
|
||||||
|
|
||||||
start = (size_t)p;
|
start = (size_t)p;
|
||||||
end = start + size;
|
end = start + size;
|
||||||
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||||
@ -470,10 +498,7 @@ void __bound_new_region(void *p, size_t size)
|
|||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
#ifdef BOUND_DEBUG
|
|
||||||
printf("new %lx %lx %x %x %x %x\n",
|
|
||||||
start, end, t1_start, t1_end, t2_start, t2_end);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
e = (BoundEntry *)((char *)page + t2_start);
|
e = (BoundEntry *)((char *)page + t2_start);
|
||||||
add_region(e, start, size);
|
add_region(e, start, size);
|
||||||
@ -515,6 +540,9 @@ void __bound_new_region(void *p, size_t size)
|
|||||||
}
|
}
|
||||||
add_region(e, start, size);
|
add_region(e, start, size);
|
||||||
}
|
}
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete a region */
|
/* delete a region */
|
||||||
@ -567,6 +595,10 @@ int __bound_delete_region(void *p)
|
|||||||
BoundEntry *page, *e, *e2;
|
BoundEntry *page, *e, *e2;
|
||||||
size_t t1_start, t1_end, t2_start, t2_end, i;
|
size_t t1_start, t1_end, t2_start, t2_end, i;
|
||||||
|
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
|
|
||||||
start = (size_t)p;
|
start = (size_t)p;
|
||||||
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||||
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
@ -633,6 +665,11 @@ int __bound_delete_region(void *p)
|
|||||||
}
|
}
|
||||||
delete_region(e, p, empty_size);
|
delete_region(e, p, empty_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,6 +755,11 @@ void *__bound_malloc(size_t size, const void *caller)
|
|||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n",
|
||||||
|
__FILE__, __FUNCTION__, ptr, size);
|
||||||
|
#endif
|
||||||
__bound_new_region(ptr, size);
|
__bound_new_region(ptr, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -747,6 +789,11 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
|
|||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef BOUND_DEBUG
|
||||||
|
fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n",
|
||||||
|
__FILE__, __FUNCTION__, ptr, size);
|
||||||
|
#endif
|
||||||
__bound_new_region(ptr, size);
|
__bound_new_region(ptr, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -861,7 +908,7 @@ void *__bound_memset(void *dst, int c, size_t size)
|
|||||||
int __bound_strlen(const char *s)
|
int __bound_strlen(const char *s)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
@ -881,4 +928,3 @@ char *__bound_strcpy(char *dst, const char *src)
|
|||||||
len = __bound_strlen(src);
|
len = __bound_strlen(src);
|
||||||
return __bound_memcpy(dst, src, len + 1);
|
return __bound_memcpy(dst, src, len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
tccelf.c
2
tccelf.c
@ -1577,7 +1577,7 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* XXX: add an object file to do that */
|
/* XXX: add an object file to do that */
|
||||||
ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
|
ptr = section_ptr_add(bounds_section, sizeof(*ptr));
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
add_elf_sym(symtab_section, 0, 0,
|
add_elf_sym(symtab_section, 0, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user