History

Add linenumber filename support for bounds checking.

herman ten brugge committed 6 years ago

Commit 87639aa1 parent 56e70bf3 files · +154 −124Browse files

Unified · Split

3 files
  1. i386-gen.c +25 −18
  2. lib/bcheck.c +91 −85
  3. x86_64-gen.c +38 −21
i386-gen.c+25−18
@@ -1130,29 +1130,36 @@ ST_FUNC void gen_bounded_ptr_add(void) · 1129 unmodified lines
11301130 {
11311131 /* save all temporary registers */
11321132 save_regs(0);
1133− /* trick to get line/file_name in code */
1134− o(0xb8);
1135− gen_le32 (file->line_num);
1136− {
1137− int i;
1138− int len;
1139− char *cp = file->filename;
1140− while (*cp) cp++;
1141− while (cp != file->filename && cp[-1] != '/') cp--;
1142− len = strlen (cp);
1143− while (len > 0) {
1144− memcpy (&i, cp, 4);
1145− o(0xb8);
1146− gen_le32 (i);
1147− cp += 4;
1148− len -= 4;
1149− }
1150− }
11511133 /* prepare fast i386 function call (args in eax and edx) */
11521134 gv2(RC_EAX, RC_EDX);
11531135 vtop -= 2;
1136+ /* add line, filename */
1137+ {
1138+ static addr_t offset;
1139+ static char last_filename[1024];
1140+ Sym *sym_data;
1141+
1142+ if (strcmp (last_filename, file->filename) != 0) {
1143+ void *ptr;
1144+ int len = strlen (file->filename) + 1;
1145+
1146+ offset = data_section->data_offset;
1147+ ptr = section_ptr_add(data_section, len);
1148+ memcpy (ptr, file->filename, len);
1149+ memcpy (last_filename, file->filename, len);
1150+ }
1151+ o(0xb9); /* mov $xx,%ecx */
1152+ gen_le32 (0);
1153+ sym_data = get_sym_ref(&char_pointer_type, data_section,
1154+ offset, data_section->data_offset);
1155+ greloca(cur_text_section, sym_data, ind - 4, R_386_32, 0);
1156+ o(0x51); /* push %ecx */
1157+ }
1158+ o(0xb9); /* mov $xx,%ecx */
1159+ gen_le32 (file->line_num);
11541160 /* do a fast function call */
11551161 gen_static_call(TOK___bound_ptr_add);
1162+ o(0x04c483); /* add $4,%esp */
11561163 /* returned pointer is in eax */
11571164 vtop++;
11581165 vtop->r = TREG_EAX | VT_BOUNDED;
lib/bcheck.c+91−85
@@ -221,7 +221,8 @@ static void bound_alloc_error(void) · 220 unmodified lines
221221
222222 /* return '(p + offset)' for pointer arithmetic (a pointer can reach
223223 the end of a region in this case */
224−void * FASTCALL __bound_ptr_add(void *p, size_t offset)
224+void * FASTCALL __bound_ptr_add(void *p, size_t offset,
225+ size_t line, const char *filename)
225226 {
226227 size_t addr = (size_t)p;
227228
@@ -229,8 +230,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 1 unmodified line
229230 return p + offset;
230231 }
231232
232− dprintf(stderr, "%s %s: %p 0x%x\n",
233− __FILE__, __FUNCTION__, p, (unsigned)offset);
233+ dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n",
234+ __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset);
234235
235236 WAIT_SEM ();
236237 INCR_COUNT(bound_ptr_add_count);
@@ -249,8 +250,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 12 unmodified lines
249250 if (addr <= tree->size) {
250251 addr += offset;
251252 if (tree->is_invalid || addr > tree->size) {
252− fprintf(stderr,"%s %s: %p is outside of the region\n",
253− __FILE__, __FUNCTION__, p + offset);
253+ fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n",
254+ __FILE__, __FUNCTION__, filename, line, p + offset);
254255 if (never_fatal == 0) {
255256 POST_SEM ();
256257 return INVALID_POINTER; /* return an invalid pointer */
@@ -264,44 +265,45 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 7 unmodified lines
264265
265266 /* return '(p + offset)' for pointer indirection (the resulting must
266267 be strictly inside the region */
267−#define BOUND_PTR_INDIR(dsize) \
268−void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
269−{ \
270− size_t addr = (size_t)p; \
271− \
272− if (no_checking) { \
273− return p + offset; \
274− } \
275− dprintf(stderr, "%s %s: %p 0x%x start\n", \
276− __FILE__, __FUNCTION__, p, (unsigned)offset); \
277− WAIT_SEM (); \
278− INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
279− if (tree) { \
280− addr -= tree->start; \
281− if (addr >= tree->size) { \
282− addr = (size_t)p; \
283− tree = splay (addr, tree); \
284− addr -= tree->start; \
285− } \
286− if (addr >= tree->size) { \
287− addr = (size_t)p; \
288− tree = splay_end (addr, tree); \
289− addr -= tree->start; \
290− } \
291− if (addr <= tree->size) { \
292− addr += offset + dsize; \
293− if (tree->is_invalid || addr > tree->size) { \
294− fprintf(stderr,"%s %s: %p is outside of the region\n", \
295− __FILE__, __FUNCTION__, p + offset); \
296− if (never_fatal == 0) { \
297− POST_SEM (); \
298− return INVALID_POINTER; /* return an invalid pointer */ \
299− } \
300− } \
301− } \
302− } \
303− POST_SEM (); \
304− return p + offset; \
268+#define BOUND_PTR_INDIR(dsize) \
269+void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \
270+ size_t line, const char *filename) \
271+{ \
272+ size_t addr = (size_t)p; \
273+ \
274+ if (no_checking) { \
275+ return p + offset; \
276+ } \
277+ dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \
278+ __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \
279+ WAIT_SEM (); \
280+ INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
281+ if (tree) { \
282+ addr -= tree->start; \
283+ if (addr >= tree->size) { \
284+ addr = (size_t)p; \
285+ tree = splay (addr, tree); \
286+ addr -= tree->start; \
287+ } \
288+ if (addr >= tree->size) { \
289+ addr = (size_t)p; \
290+ tree = splay_end (addr, tree); \
291+ addr -= tree->start; \
292+ } \
293+ if (addr <= tree->size) { \
294+ addr += offset + dsize; \
295+ if (tree->is_invalid || addr > tree->size) { \
296+ fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \
297+ __FILE__, __FUNCTION__, filename, line, p + offset); \
298+ if (never_fatal == 0) { \
299+ POST_SEM (); \
300+ return INVALID_POINTER; /* return an invalid pointer */ \
301+ } \
302+ } \
303+ } \
304+ } \
305+ POST_SEM (); \
306+ return p + offset; \
305307 }
306308
307309 BOUND_PTR_INDIR(1)
@@ -540,7 +542,7 @@ void __attribute__((destructor)) __bound_exit(void) · 232 unmodified lines
540542 }
541543 while (tree) {
542544 if (print_heap && tree->type != 0) {
543− fprintf (stderr, "%s, %s() %s found size %ld\n",
545+ fprintf (stderr, "%s, %s() %s found size %lu\n",
544546 __FILE__, __FUNCTION__, alloc_type[tree->type],
545547 (unsigned long) tree->size);
546548 }
@@ -621,7 +623,7 @@ void *__bound_malloc(size_t size, const void *caller) · 74 unmodified lines
621623
622624 if (ptr) {
623625 tree = splay_insert ((size_t) ptr, size, tree);
624− if (tree->start == (size_t) ptr) {
626+ if (tree && tree->start == (size_t) ptr) {
625627 tree->type = TCC_TYPE_MALLOC;
626628 }
627629 }
@@ -666,7 +668,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 38 unmodified lines
666668 dprintf(stderr, "%s, %s (%p, 0x%x)\n",
667669 __FILE__, __FUNCTION__, ptr, (unsigned)size);
668670 tree = splay_insert((size_t) ptr, size, tree);
669− if (tree->start == (size_t) ptr) {
671+ if (tree && tree->start == (size_t) ptr) {
670672 tree->type = TCC_TYPE_MEMALIGN;
671673 }
672674 }
@@ -744,7 +746,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 71 unmodified lines
744746 INCR_COUNT(bound_realloc_count);
745747 if (ptr) {
746748 tree = splay_insert ((size_t) ptr, size, tree);
747− if (tree->start == (size_t) ptr) {
749+ if (tree && tree->start == (size_t) ptr) {
748750 tree->type = TCC_TYPE_REALLOC;
749751 }
750752 }
@@ -761,7 +763,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 10 unmodified lines
761763 #endif
762764 if (ptr) {
763765 tree = splay_insert ((size_t) ptr, size, tree);
764− if (tree->start == (size_t) ptr) {
766+ if (tree && tree->start == (size_t) ptr) {
765767 tree->type = TCC_TYPE_REALLOC;
766768 }
767769 }
@@ -800,7 +802,7 @@ void *__bound_calloc(size_t nmemb, size_t size) · 32 unmodified lines
800802 WAIT_SEM ();
801803 INCR_COUNT(bound_calloc_count);
802804 tree = splay_insert ((size_t) ptr, size, tree);
803− if (tree->start == (size_t) ptr) {
805+ if (tree && tree->start == (size_t) ptr) {
804806 tree->type = TCC_TYPE_CALLOC;
805807 }
806808 POST_SEM ();
@@ -899,13 +901,13 @@ void __bound_new_region(void *p, size_t size) · 92 unmodified lines
899901 /* some useful checked functions */
900902
901903 /* check that (p ... p + size - 1) lies inside 'p' region, if any */
902−static void __bound_check(const void *p, size_t size)
904+static void __bound_check(const void *p, size_t size, const char *function)
903905 {
904906 if (no_checking)
905907 return;
906908 if (size == 0)
907909 return;
908− p = __bound_ptr_add((void *)p, size);
910+ p = __bound_ptr_add((void *)p, size, 0, function);
909911 if (p == INVALID_POINTER)
910912 bound_error("invalid pointer");
911913 }
@@ -915,8 +917,8 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 3 unmodified lines
915917 void* p;
916918
917919 INCR_COUNT(bound_mempcy_count);
918− __bound_check(dst, size);
919− __bound_check(src, size);
920+ __bound_check(dst, size, "memcpy");
921+ __bound_check(src, size, "memcpy");
920922 /* check also region overlap */
921923 if (no_checking == 0 && src >= dst && src < dst + size)
922924 bound_error("overlapping regions in memcpy()");
@@ -929,23 +931,23 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 6 unmodified lines
929931 int __bound_memcmp(const void *s1, const void *s2, size_t size)
930932 {
931933 INCR_COUNT(bound_memcmp_count);
932− __bound_check(s1, size);
933− __bound_check(s2, size);
934+ __bound_check(s1, size, "memcmp");
935+ __bound_check(s2, size, "memcmp");
934936 return memcmp(s1, s2, size);
935937 }
936938
937939 void *__bound_memmove(void *dst, const void *src, size_t size)
938940 {
939941 INCR_COUNT(bound_memmove_count);
940− __bound_check(dst, size);
941− __bound_check(src, size);
942+ __bound_check(dst, size, "memmove");
943+ __bound_check(src, size, "memmove");
942944 return memmove(dst, src, size);
943945 }
944946
945947 void *__bound_memset(void *dst, int c, size_t size)
946948 {
947949 INCR_COUNT(bound_memset_count);
948− __bound_check(dst, size);
950+ __bound_check(dst, size, "memset");
949951 return memset(dst, c, size);
950952 }
951953
@@ -957,7 +959,7 @@ int __bound_strlen(const char *s) · 5 unmodified lines
957959 INCR_COUNT(bound_strlen_count);
958960 while (*p++);
959961 len = (p - s) - 1;
960− p = __bound_ptr_indir1((char *)s, len);
962+ p = __bound_ptr_indir1((char *)s, len, 0, "strlen");
961963 if (p == INVALID_POINTER)
962964 bound_error("bad pointer in strlen()");
963965 return len;
@@ -982,8 +984,8 @@ char *__bound_strncpy(char *dst, const char *src, size_t n) · 18 unmodified lines
982984 while (len-- && *p++);
983985 len = p - src;
984986 INCR_COUNT(bound_strncpy_count);
985− __bound_check(dst, len);
986− __bound_check(src, len);
987+ __bound_check(dst, len, "strncpy");
988+ __bound_check(src, len, "strncpy");
987989 return strncpy (dst, src, n);
988990 }
989991
@@ -997,8 +999,8 @@ int __bound_strcmp(const char *s1, const char *s2) · 7 unmodified lines
997999 u1++;
9981000 u2++;
9991001 }
1000− __bound_check(s1, ((const char *)u1 - s1) + 1);
1001− __bound_check(s2, ((const char *)u2 - s2) + 1);
1002+ __bound_check(s1, ((const char *)u1 - s1) + 1, "strcmp");
1003+ __bound_check(s2, ((const char *)u2 - s2) + 1, "strcmp");
10021004 return (*u1 - *u2);
10031005 }
10041006
@@ -1018,8 +1020,8 @@ int __bound_strncmp(const char *s1, const char *s2, size_t n) · 13 unmodified lines
10181020 }
10191021 u2++;
10201022 } while (*u1++);
1021− __bound_check(s1, ((const char *)u1 - s1) + 1);
1022− __bound_check(s2, ((const char *)u1 - s1) + 1);
1023+ __bound_check(s1, ((const char *)u1 - s1) + 1, "strncmp");
1024+ __bound_check(s2, ((const char *)u1 - s1) + 1, "strncmp");
10231025 return retval;
10241026 }
10251027
@@ -1032,8 +1034,8 @@ char *__bound_strcat(char *dest, const char *src) · 6 unmodified lines
10321034 while (*dest++);
10331035 dest--;
10341036 while ((*dest++ = *src++) != 0);
1035− __bound_check(r, dest - r);
1036− __bound_check(s, src - s);
1037+ __bound_check(r, dest - r, "strcat");
1038+ __bound_check(s, src - s, "strcat");
10371039 return r;
10381040 }
10391041
@@ -1049,7 +1051,7 @@ char *__bound_strchr(const char *string, int ch) · 9 unmodified lines
10491051 }
10501052 s++;
10511053 }
1052− __bound_check(string, ((const char *)s - string) + 1);
1054+ __bound_check(string, ((const char *)s - string) + 1, "strchr");
10531055 return *s == c ? (char *) s : NULL;
10541056 }
10551057
@@ -1060,7 +1062,7 @@ char *__bound_strdup(const char *s) · 4 unmodified lines
10601062
10611063 INCR_COUNT(bound_strdup_count);
10621064 while (*p++);
1063− __bound_check(s, p - s);
1065+ __bound_check(s, p - s, "strdup");
10641066 #if MALLOC_REDIR
10651067 new = malloc_redir (p - s);
10661068 #else
@@ -1069,7 +1071,7 @@ char *__bound_strdup(const char *s) · 2 unmodified lines
10691071 if (new) {
10701072 WAIT_SEM ();
10711073 tree = splay_insert((size_t)new, p - s, tree);
1072− if (tree->start == (size_t) new) {
1074+ if (tree && tree->start == (size_t) new) {
10731075 tree->type = TCC_TYPE_STRDUP;
10741076 }
10751077 memcpy (new, s, p - s);
@@ -1261,22 +1263,26 @@ static Tree * splay_insert(size_t addr, size_t size, Tree * t) · 185 unmodified lines
12611263 new = (Tree *) malloc (sizeof (Tree));
12621264 #endif
12631265 }
1264− if (new == NULL) {bound_alloc_error();}
1265− if (t == NULL) {
1266− new->left = new->right = NULL;
1267− } else if (compare(addr, t->start, t->size) < 0) {
1268− new->left = t->left;
1269− new->right = t;
1270− t->left = NULL;
1271− } else {
1272− new->right = t->right;
1273− new->left = t;
1274− t->right = NULL;
1266+ if (new == NULL) {
1267+ bound_alloc_error();
1268+ }
1269+ else {
1270+ if (t == NULL) {
1271+ new->left = new->right = NULL;
1272+ } else if (compare(addr, t->start, t->size) < 0) {
1273+ new->left = t->left;
1274+ new->right = t;
1275+ t->left = NULL;
1276+ } else {
1277+ new->right = t->right;
1278+ new->left = t;
1279+ t->right = NULL;
1280+ }
1281+ new->start = addr;
1282+ new->size = size;
1283+ new->type = TCC_TYPE_NONE;
1284+ new->is_invalid = 0;
12751285 }
1276− new->start = addr;
1277− new->size = size;
1278− new->type = TCC_TYPE_NONE;
1279− new->is_invalid = 0;
12801286 return new;
12811287 }
12821288
x86_64-gen.c+38−21
@@ -767,28 +767,12 @@ ST_FUNC void gen_bounded_ptr_add(void) · 766 unmodified lines
767767
768768 if (nested_call > 1) {
769769 #ifdef TCC_TARGET_PE
770− o(0x5152); /* push %rcx/%rdx */
770+ o(0x5152); /* push %rdx/%rcx */
771+ o(0x51415041); /* push %r8/%r9 */
771772 #else
772− o(0x5657); /* push %rdi/%rsi */
773+ o(0x51525657); /* push %rdi/%rsi/%rdx/%rcx */
773774 #endif
774775 }
775− /* trick to get line/file_name in code */
776− o(0xb8);
777− gen_le32 (file->line_num);
778− {
779− int len;
780− char *cp = file->filename;
781− while (*cp) cp++;
782− while (cp != file->filename && cp[-1] != '/') cp--;
783− len = strlen (cp);
784− while (len > 0) {
785− memcpy (&i, cp, 4);
786− o(0xb8);
787− gen_le32 (i);
788− cp += 4;
789− len -= 4;
790− }
791− }
792776 /* prepare fast x86_64 function call */
793777 gv(RC_RAX);
794778 #ifdef TCC_TARGET_PE
@@ -806,6 +790,38 @@ ST_FUNC void gen_bounded_ptr_add(void) · 11 unmodified lines
806790 #endif
807791 vtop--;
808792
793+ /* add line, filename */
794+#ifdef TCC_TARGET_PE
795+ o(0xc0c749); /* mov $xx,%r8 */
796+#else
797+ o(0xba); /* mov $xx,%edx */
798+#endif
799+ gen_le32 (file->line_num);
800+ {
801+ static addr_t offset;
802+ static char last_filename[1024];
803+ Sym *sym_data;
804+
805+ if (strcmp (last_filename, file->filename) != 0) {
806+ void *ptr;
807+ int len = strlen (file->filename) + 1;
808+
809+ offset = data_section->data_offset;
810+ ptr = section_ptr_add(data_section, len);
811+ memcpy (ptr, file->filename, len);
812+ memcpy (last_filename, file->filename, len);
813+ }
814+#ifdef TCC_TARGET_PE
815+ o(0xb949); /* mov $xx,%r9 */
816+#else
817+ o(0xb948); /* mov $xx,%rcx */
818+#endif
819+ gen_le64 (0);
820+ sym_data = get_sym_ref(&char_pointer_type, data_section,
821+ offset, data_section->data_offset);
822+ greloca(cur_text_section, sym_data, ind - 8, R_X86_64_64, 0);
823+ }
824+
809825 #ifdef TCC_TARGET_PE
810826 o(0x20ec8348); /* sub $20, %rsp */
811827 #endif
@@ -819,9 +835,10 @@ ST_FUNC void gen_bounded_ptr_add(void) · 7 unmodified lines
819835
820836 if (nested_call > 1) {
821837 #ifdef TCC_TARGET_PE
822− o(0x5a59); /* pop %rcx/%rdx */
838+ o(0x58415941); /* pop %r9/%r8 */
839+ o(0x5a59); /* pop %rcx/%rdx */
823840 #else
824− o(0x5f5e); /* pop %rsi/%rdi */
841+ o(0x5f5e5a59); /* pop $rcx/%rdx/%rsi/%rdi */
825842 #endif
826843 }
827844 /* returned pointer is in rax */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t