| @@ -31,6 +31,12 @@ · 30 unmodified lines |
| 31 | | 31 | |
| 32 | /* #define BOUND_DEBUG */ | 32 | /* #define BOUND_DEBUG */ |
| 33 | | 33 | |
| | 34 | #ifdef BOUND_DEBUG |
| | 35 | #define dprintf(a...) fprintf(a) |
| | 36 | #else |
| | 37 | #define dprintf(a...) |
| | 38 | #endif |
| | 39 | |
| 34 | /* define so that bound array is static (faster, but use memory if | 40 | /* define so that bound array is static (faster, but use memory if |
| 35 | bound checking not used) */ | 41 | bound checking not used) */ |
| 36 | /* #define BOUND_STATIC */ | 42 | /* #define BOUND_STATIC */ |
| @@ -50,12 +56,12 @@ · 13 unmodified lines |
| 50 | | 56 | |
| 51 | #define BOUND_T1_BITS 13 | 57 | #define BOUND_T1_BITS 13 |
| 52 | #define BOUND_T2_BITS 11 | 58 | #define BOUND_T2_BITS 11 |
| 53 | #define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS) | 59 | #define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS) |
| | 60 | #define BOUND_E_BITS (sizeof(size_t)) |
| 54 | | 61 | |
| 55 | #define BOUND_T1_SIZE (1 << BOUND_T1_BITS) | 62 | #define BOUND_T1_SIZE (1 << BOUND_T1_BITS) |
| 56 | #define BOUND_T2_SIZE (1 << BOUND_T2_BITS) | 63 | #define BOUND_T2_SIZE (1 << BOUND_T2_BITS) |
| 57 | #define BOUND_T3_SIZE (1 << BOUND_T3_BITS) | 64 | #define BOUND_T3_SIZE (1 << BOUND_T3_BITS) |
| 58 | #define BOUND_E_BITS 4 | | |
| 59 | | 65 | |
| 60 | #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) | 66 | #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) |
| 61 | #define BOUND_T23_SIZE (1 << BOUND_T23_BITS) | 67 | #define BOUND_T23_SIZE (1 << BOUND_T23_BITS) |
| @@ -64,7 +70,7 @@ · 2 unmodified lines |
| 64 | /* this pointer is generated when bound check is incorrect */ | 70 | /* this pointer is generated when bound check is incorrect */ |
| 65 | #define INVALID_POINTER ((void *)(-2)) | 71 | #define INVALID_POINTER ((void *)(-2)) |
| 66 | /* size of an empty region */ | 72 | /* size of an empty region */ |
| 67 | #define EMPTY_SIZE 0xffffffff | 73 | #define EMPTY_SIZE ((size_t)(-1)) |
| 68 | /* size of an invalid region */ | 74 | /* size of an invalid region */ |
| 69 | #define INVALID_SIZE 0 | 75 | #define INVALID_SIZE 0 |
| 70 | | 76 | |
| @@ -168,9 +174,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 97 unmodified lines |
| 168 | | 174 | |
| 169 | __bound_init(); | 175 | __bound_init(); |
| 170 | | 176 | |
| 171 | #if defined(BOUND_DEBUG) | 177 | dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset); |
| 172 | printf("%s %s: 0x%x %d\n", __FILE__, __FUNCTION__, (int)p, offset); | | |
| 173 | #endif | | |
| 174 | | 178 | |
| 175 | e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; | 179 | e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; |
| 176 | e = (BoundEntry *)((char *)e + | 180 | e = (BoundEntry *)((char *)e + |
| @@ -197,6 +201,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 20 unmodified lines |
| 197 | size_t addr = (size_t)p; \ | 201 | size_t addr = (size_t)p; \ |
| 198 | BoundEntry *e; \ | 202 | BoundEntry *e; \ |
| 199 | \ | 203 | \ |
| | 204 | dprintf(stderr, "%s %s: %p %p start\n", __FILE__, __FUNCTION__, p, offset); \ |
| | 205 | \ |
| 200 | __bound_init(); \ | 206 | __bound_init(); \ |
| 201 | e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ | 207 | e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ |
| 202 | e = (BoundEntry *)((char *)e + \ | 208 | e = (BoundEntry *)((char *)e + \ |
| @@ -212,6 +218,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 9 unmodified lines |
| 212 | fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); \ | 218 | fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); \ |
| 213 | return INVALID_POINTER; /* return an invalid pointer */ \ | 219 | return INVALID_POINTER; /* return an invalid pointer */ \ |
| 214 | } \ | 220 | } \ |
| | 221 | dprintf(stderr, "%s %s: return p+offset = %p\n", __FILE__, __FUNCTION__, p + offset); \ |
| 215 | return p + offset; \ | 222 | return p + offset; \ |
| 216 | } | 223 | } |
| 217 | | 224 | |
| @@ -232,9 +239,8 @@ BOUND_PTR_INDIR(16) · 14 unmodified lines |
| 232 | void FASTCALL __bound_local_new(void *p1) | 239 | void FASTCALL __bound_local_new(void *p1) |
| 233 | { | 240 | { |
| 234 | size_t addr, size, fp, *p = p1; | 241 | size_t addr, size, fp, *p = p1; |
| 235 | #ifdef BOUND_DEBUG | 242 | |
| 236 | fprintf(stderr, "%s, %s start p1=%p *p1=%p\n", __FILE__, __FUNCTION__, p, *p); | 243 | dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p); |
| 237 | #endif | | |
| 238 | GET_CALLER_FP(fp); | 244 | GET_CALLER_FP(fp); |
| 239 | for(;;) { | 245 | for(;;) { |
| 240 | addr = p[0]; | 246 | addr = p[0]; |
| @@ -245,9 +251,7 @@ void FASTCALL __bound_local_new(void *p1) · 4 unmodified lines |
| 245 | p += 2; | 251 | p += 2; |
| 246 | __bound_new_region((void *)addr, size); | 252 | __bound_new_region((void *)addr, size); |
| 247 | } | 253 | } |
| 248 | #ifdef BOUND_DEBUG | 254 | dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); |
| 249 | fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); | | |
| 250 | #endif | | |
| 251 | } | 255 | } |
| 252 | | 256 | |
| 253 | /* called when leaving a function to delete all the local regions */ | 257 | /* called when leaving a function to delete all the local regions */ |
| @@ -268,7 +272,7 @@ void FASTCALL __bound_local_delete(void *p1) · 14 unmodified lines |
| 268 | static BoundEntry *__bound_new_page(void) | 272 | static BoundEntry *__bound_new_page(void) |
| 269 | { | 273 | { |
| 270 | BoundEntry *page; | 274 | BoundEntry *page; |
| 271 | int i; | 275 | size_t i; |
| 272 | | 276 | |
| 273 | page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); | 277 | page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); |
| 274 | if (!page) | 278 | if (!page) |
| @@ -296,11 +300,11 @@ static void bound_free_entry(BoundEntry *e) · 21 unmodified lines |
| 296 | libc_free(e); | 300 | libc_free(e); |
| 297 | } | 301 | } |
| 298 | | 302 | |
| 299 | static inline BoundEntry *get_page(int index) | 303 | static BoundEntry *get_page(size_t index) |
| 300 | { | 304 | { |
| 301 | BoundEntry *page; | 305 | BoundEntry *page; |
| 302 | page = __bound_t1[index]; | 306 | page = __bound_t1[index]; |
| 303 | if (page == __bound_empty_t2 || page == __bound_invalid_t2) { | 307 | if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) { |
| 304 | /* create a new page if necessary */ | 308 | /* create a new page if necessary */ |
| 305 | page = __bound_new_page(); | 309 | page = __bound_new_page(); |
| 306 | __bound_t1[index] = page; | 310 | __bound_t1[index] = page; |
| @@ -325,7 +329,7 @@ static void mark_invalid(size_t addr, size_t size) · 18 unmodified lines |
| 325 | t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS); | 329 | t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS); |
| 326 | | 330 | |
| 327 | #if 0 | 331 | #if 0 |
| 328 | printf("mark_invalid: start = %x %x\n", t2_start, t2_end); | 332 | dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); |
| 329 | #endif | 333 | #endif |
| 330 | | 334 | |
| 331 | /* first we handle full pages */ | 335 | /* first we handle full pages */ |
| @@ -364,7 +368,7 @@ static void mark_invalid(size_t addr, size_t size) · 32 unmodified lines |
| 364 | | 368 | |
| 365 | void __bound_init(void) | 369 | void __bound_init(void) |
| 366 | { | 370 | { |
| 367 | int i; | 371 | size_t i; |
| 368 | BoundEntry *page; | 372 | BoundEntry *page; |
| 369 | size_t start, size; | 373 | size_t start, size; |
| 370 | size_t *p; | 374 | size_t *p; |
| @@ -375,9 +379,7 @@ void __bound_init(void) · 4 unmodified lines |
| 375 | | 379 | |
| 376 | inited = 1; | 380 | inited = 1; |
| 377 | | 381 | |
| 378 | #ifdef BOUND_DEBUG | 382 | dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); |
| 379 | fprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); | | |
| 380 | #endif | | |
| 381 | | 383 | |
| 382 | /* save malloc hooks and install bound check hooks */ | 384 | /* save malloc hooks and install bound check hooks */ |
| 383 | install_malloc_hooks(); | 385 | install_malloc_hooks(); |
| @@ -445,19 +447,18 @@ void __bound_init(void) · 61 unmodified lines |
| 445 | __bound_new_region((void *)p[0], p[1]); | 447 | __bound_new_region((void *)p[0], p[1]); |
| 446 | p += 2; | 448 | p += 2; |
| 447 | } | 449 | } |
| 448 | #ifdef BOUND_DEBUG | 450 | |
| 449 | fprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__); | 451 | dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__); |
| 450 | #endif | | |
| 451 | } | 452 | } |
| 452 | | 453 | |
| 453 | void __bound_main_arg(void **p) | 454 | void __bound_main_arg(void **p) |
| 454 | { | 455 | { |
| 455 | void *start = p; | 456 | void *start = p; |
| 456 | while (*p++); | 457 | while (*p++); |
| 457 | #ifdef BOUND_DEBUG | 458 | |
| 458 | fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | 459 | dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", |
| 459 | __FILE__, __FUNCTION__, (void *) p - start); | 460 | __FILE__, __FUNCTION__, (void *) p - start); |
| 460 | #endif | 461 | |
| 461 | __bound_new_region(start, (void *) p - start); | 462 | __bound_new_region(start, (void *) p - start); |
| 462 | } | 463 | } |
| 463 | | 464 | |
| @@ -495,10 +496,8 @@ void __bound_new_region(void *p, size_t size) · 31 unmodified lines |
| 495 | | 496 | |
| 496 | __bound_init(); | 497 | __bound_init(); |
| 497 | | 498 | |
| 498 | #ifdef BOUND_DEBUG | 499 | dprintf(stderr, "%s, %s(%p, %p) start\n", |
| 499 | fprintf(stderr, "%s, %s(%p, %p) start\n", | | |
| 500 | __FILE__, __FUNCTION__, p, size); | 500 | __FILE__, __FUNCTION__, p, size); |
| 501 | #endif | | |
| 502 | | 501 | |
| 503 | start = (size_t)p; | 502 | start = (size_t)p; |
| 504 | end = start + size; | 503 | end = start + size; |
| @@ -553,9 +552,8 @@ void __bound_new_region(void *p, size_t size) · 48 unmodified lines |
| 553 | } | 552 | } |
| 554 | add_region(e, start, size); | 553 | add_region(e, start, size); |
| 555 | } | 554 | } |
| 556 | #ifdef BOUND_DEBUG | 555 | |
| 557 | fprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); | 556 | dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); |
| 558 | #endif | | |
| 559 | } | 557 | } |
| 560 | | 558 | |
| 561 | /* delete a region */ | 559 | /* delete a region */ |
| @@ -610,9 +608,7 @@ int __bound_delete_region(void *p) · 48 unmodified lines |
| 610 | | 608 | |
| 611 | __bound_init(); | 609 | __bound_init(); |
| 612 | | 610 | |
| 613 | #ifdef BOUND_DEBUG | 611 | dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); |
| 614 | fprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); | | |
| 615 | #endif | | |
| 616 | | 612 | |
| 617 | start = (size_t)p; | 613 | start = (size_t)p; |
| 618 | t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); | 614 | t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); |
| @@ -681,9 +677,7 @@ int __bound_delete_region(void *p) · 62 unmodified lines |
| 681 | delete_region(e, p, empty_size); | 677 | delete_region(e, p, empty_size); |
| 682 | } | 678 | } |
| 683 | | 679 | |
| 684 | #ifdef BOUND_DEBUG | 680 | dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__); |
| 685 | fprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__); | | |
| 686 | #endif | | |
| 687 | | 681 | |
| 688 | return 0; | 682 | return 0; |
| 689 | } | 683 | } |
| @@ -771,10 +765,9 @@ void *__bound_malloc(size_t size, const void *caller) · 81 unmodified lines |
| 771 | if (!ptr) | 765 | if (!ptr) |
| 772 | return NULL; | 766 | return NULL; |
| 773 | | 767 | |
| 774 | #ifdef BOUND_DEBUG | 768 | dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", |
| 775 | fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | | |
| 776 | __FILE__, __FUNCTION__, ptr, size); | 769 | __FILE__, __FUNCTION__, ptr, size); |
| 777 | #endif | 770 | |
| 778 | __bound_new_region(ptr, size); | 771 | __bound_new_region(ptr, size); |
| 779 | return ptr; | 772 | return ptr; |
| 780 | } | 773 | } |
| @@ -805,10 +798,9 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 24 unmodified lines |
| 805 | if (!ptr) | 798 | if (!ptr) |
| 806 | return NULL; | 799 | return NULL; |
| 807 | | 800 | |
| 808 | #ifdef BOUND_DEBUG | 801 | dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", |
| 809 | fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | | |
| 810 | __FILE__, __FUNCTION__, ptr, size); | 802 | __FILE__, __FUNCTION__, ptr, size); |
| 811 | #endif | 803 | |
| 812 | __bound_new_region(ptr, size); | 804 | __bound_new_region(ptr, size); |
| 813 | return ptr; | 805 | return ptr; |
| 814 | } | 806 | } |
| @@ -861,23 +853,23 @@ void *__bound_calloc(size_t nmemb, size_t size) · 46 unmodified lines |
| 861 | static void bound_dump(void) | 853 | static void bound_dump(void) |
| 862 | { | 854 | { |
| 863 | BoundEntry *page, *e; | 855 | BoundEntry *page, *e; |
| 864 | int i, j; | 856 | size_t i, j; |
| 865 | | 857 | |
| 866 | printf("region dump:\n"); | 858 | fprintf(stderr, "region dump:\n"); |
| 867 | for(i=0;i<BOUND_T1_SIZE;i++) { | 859 | for(i=0;i<BOUND_T1_SIZE;i++) { |
| 868 | page = __bound_t1[i]; | 860 | page = __bound_t1[i]; |
| 869 | for(j=0;j<BOUND_T2_SIZE;j++) { | 861 | for(j=0;j<BOUND_T2_SIZE;j++) { |
| 870 | e = page + j; | 862 | e = page + j; |
| 871 | /* do not print invalid or empty entries */ | 863 | /* do not print invalid or empty entries */ |
| 872 | if (e->size != EMPTY_SIZE && e->start != 0) { | 864 | if (e->size != EMPTY_SIZE && e->start != 0) { |
| 873 | printf("%08x:", | 865 | fprintf(stderr, "%08x:", |
| 874 | (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + | 866 | (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + |
| 875 | (j << BOUND_T3_BITS)); | 867 | (j << BOUND_T3_BITS)); |
| 876 | do { | 868 | do { |
| 877 | printf(" %08lx:%08lx", e->start, e->start + e->size); | 869 | fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); |
| 878 | e = e->next; | 870 | e = e->next; |
| 879 | } while (e != NULL); | 871 | } while (e != NULL); |
| 880 | printf("\n"); | 872 | fprintf(stderr, "\n"); |
| 881 | } | 873 | } |
| 882 | } | 874 | } |
| 883 | } | 875 | } |
| @@ -891,19 +883,27 @@ static void __bound_check(const void *p, size_t size) · 7 unmodified lines |
| 891 | { | 883 | { |
| 892 | if (size == 0) | 884 | if (size == 0) |
| 893 | return; | 885 | return; |
| 894 | p = __bound_ptr_add((void *)p, size); | 886 | p = __bound_ptr_add((void *)p, size - 1); |
| 895 | if (p == INVALID_POINTER) | 887 | if (p == INVALID_POINTER) |
| 896 | bound_error("invalid pointer"); | 888 | bound_error("invalid pointer"); |
| 897 | } | 889 | } |
| 898 | | 890 | |
| 899 | void *__bound_memcpy(void *dst, const void *src, size_t size) | 891 | void *__bound_memcpy(void *dst, const void *src, size_t size) |
| 900 | { | 892 | { |
| | 893 | void* p; |
| | 894 | |
| | 895 | dprintf(stderr, "%s %s: start, dst=%p src=%p size=%p\n", __FILE__, __FUNCTION__, dst, src, size); |
| | 896 | |
| 901 | __bound_check(dst, size); | 897 | __bound_check(dst, size); |
| 902 | __bound_check(src, size); | 898 | __bound_check(src, size); |
| 903 | /* check also region overlap */ | 899 | /* check also region overlap */ |
| 904 | if (src >= dst && src < dst + size) | 900 | if (src >= dst && src < dst + size) |
| 905 | bound_error("overlapping regions in memcpy()"); | 901 | bound_error("overlapping regions in memcpy()"); |
| 906 | return memcpy(dst, src, size); | 902 | |
| | 903 | p = memcpy(dst, src, size); |
| | 904 | |
| | 905 | dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p); |
| | 906 | return p; |
| 907 | } | 907 | } |
| 908 | | 908 | |
| 909 | void *__bound_memmove(void *dst, const void *src, size_t size) | 909 | void *__bound_memmove(void *dst, const void *src, size_t size) |
| @@ -939,7 +939,12 @@ int __bound_strlen(const char *s) · 29 unmodified lines |
| 939 | | 939 | |
| 940 | char *__bound_strcpy(char *dst, const char *src) | 940 | char *__bound_strcpy(char *dst, const char *src) |
| 941 | { | 941 | { |
| 942 | int len; | 942 | size_t len; |
| | 943 | void *p; |
| | 944 | |
| | 945 | dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n", __FILE__, __FUNCTION__, dst, src); |
| 943 | len = __bound_strlen(src); | 946 | len = __bound_strlen(src); |
| 944 | return __bound_memcpy(dst, src, len + 1); | 947 | p = __bound_memcpy(dst, src, len + 1); |
| | 948 | dprintf(stderr, "%s %s: strcpy end, p=%p\n", __FILE__, __FUNCTION__, dst, src, p); |
| | 949 | return p; |
| 945 | } | 950 | } |