History

Bound checking fixes

tccgen.c: - Fix 'tcc -b conftest.s' - Add offset during bound checking for struct return lib/bcheck.c: - Check overlap when reusing vla/alloca arm-gen.c: arm64-gen.c: riscv64-gen.c: lib/alloca86-bt.S: - add space for vla/alloca during bound checking tests/tests2/Makefile: tests/tests2/121_struct_return: tests/tests2/122_vla_reuse: - New test cases with bound checking enabled to test vla and struct return

herman ten brugge committed 6 years ago

Commit afc09171 parent 352e1d011 files · +104 −4Browse files

Unified · Split

11 files
  1. arm-gen.c +4 −0
  2. arm64-gen.c +5 −0
  3. lib/alloca86-bt.S +1 −1
  4. lib/bcheck.c +14 −2
  5. riscv64-gen.c +5 −0
  6. tccgen.c +5 −1
  7. tests/tests2/121_struct_return.c +35 −0
  8. tests/tests2/121_struct_return.expect +1 −0
  9. tests/tests2/122_vla_reuse.c +31 −0
  10. tests/tests2/122_vla_reuse.expect +1 −0
  11. tests/tests2/Makefile +2 −0
arm-gen.c+4−0
@@ -2255,6 +2255,10 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2254 unmodified lines
22552255 vpushv(vtop);
22562256 #endif
22572257 r = intr(gv(RC_INT));
2258+#if defined(CONFIG_TCC_BCHECK)
2259+ if (tcc_state->do_bounds_check)
2260+ o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
2261+#endif
22582262 o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
22592263 #ifdef TCC_ARM_EABI
22602264 if (align < 8)
arm64-gen.c+5−0
@@ -2046,6 +2046,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2045 unmodified lines
20462046 vpushv(vtop);
20472047 #endif
20482048 r = intr(gv(RC_INT));
2049+#if defined(CONFIG_TCC_BCHECK)
2050+ if (tcc_state->do_bounds_check)
2051+ o(0x91004000 | r | r << 5); // add x(r),x(r),#15+1
2052+ else
2053+#endif
20492054 o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
20502055 o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
20512056 o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
lib/alloca86-bt.S+1−1
@@ -12,7 +12,7 @@ _(__bound_alloca): · 11 unmodified lines
1212 pop %edx
1313 pop %eax
1414 mov %eax, %ecx
15− add $3,%eax
15+ add $3+1,%eax
1616 and $-4,%eax
1717 jz p6
1818
lib/bcheck.c+14−2
@@ -212,6 +212,7 @@ struct tree_node { · 211 unmodified lines
212212 typedef struct alloca_list_struct {
213213 size_t fp;
214214 void *p;
215+ size_t size;
215216 struct alloca_list_struct *next;
216217 } alloca_list_type;
217218
@@ -728,12 +729,22 @@ void __bound_new_region(void *p, size_t size) · 510 unmodified lines
728729 last = NULL;
729730 cur = alloca_list;
730731 while (cur) {
731− if (cur->fp == fp && cur->p == p) {
732+#if defined(__i386__) || (defined(__arm__) && !defined(TCC_ARM_EABI))
733+ int align = 4;
734+#elif defined(__arm__)
735+ int align = 8;
736+#else
737+ int align = 16;
738+#endif
739+ void *cure = (void *)((char *)cur->p + ((cur->size + align) & -align));
740+ void *pe = (void *)((char *)p + ((size + align) & -align));
741+ if (cur->fp == fp && ((cur->p <= p && cure > p) ||
742+ (p <= cur->p && pe > cur->p))) {
732743 if (last)
733744 last->next = cur->next;
734745 else
735746 alloca_list = cur->next;
736− tree = splay_delete((size_t)p, tree);
747+ tree = splay_delete((size_t)cur->p, tree);
737748 break;
738749 }
739750 last = cur;
@@ -743,6 +754,7 @@ void __bound_new_region(void *p, size_t size) · 3 unmodified lines
743754 if (new) {
744755 new->fp = fp;
745756 new->p = p;
757+ new->size = size;
746758 new->next = alloca_list;
747759 alloca_list = new;
748760 }
riscv64-gen.c+5−0
@@ -1327,6 +1327,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) · 1326 unmodified lines
13271327 vpushv(vtop);
13281328 #endif
13291329 rr = ireg(gv(RC_INT));
1330+#if defined(CONFIG_TCC_BCHECK)
1331+ if (tcc_state->do_bounds_check)
1332+ EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1
1333+ else
1334+#endif
13301335 EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15
13311336 EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16
13321337 ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
tccgen.c+5−1
@@ -413,7 +413,8 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 412 unmodified lines
413413 pstrcat(buf, sizeof(buf), "/");
414414 put_stabs_r(s1, buf, N_SO, 0, 0,
415415 text_section->data_offset, text_section, section_sym);
416− put_stabs_r(s1, file->prev->filename, N_SO, 0, 0,
416+ put_stabs_r(s1, file->prev ? file->prev->filename : file->filename,
417+ N_SO, 0, 0,
417418 text_section->data_offset, text_section, section_sym);
418419 for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
419420 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
@@ -6100,6 +6101,9 @@ special_math_val: · 5680 unmodified lines
61006101 /* pass it as 'int' to avoid structure arg passing
61016102 problems */
61026103 vseti(VT_LOCAL, loc);
6104+#ifdef CONFIG_TCC_BCHECK
6105+ loc -= tcc_state->do_bounds_check != 0;
6106+#endif
61036107 ret.c = vtop->c;
61046108 if (ret_nregs < 0)
61056109 vtop--;
tests/tests2/121_struct_return.c+35−0
@@ -0,0 +1,35 @@
1+#include <stdio.h>
2+
3+typedef struct {
4+ int data[4];
5+ double d1;
6+ double d2;
7+} Node;
8+
9+Node init(Node self) {
10+ self.data[0] = 0;
11+ self.data[1] = 1;
12+ self.data[2] = 2;
13+ self.data[3] = 3;
14+ self.d1 = 1234;
15+ self.d2 = 2345;
16+ return self;
17+}
18+
19+void dummy(Node self) {
20+}
21+
22+void print_data(Node data) {
23+ printf ("%d %d %d %d %g %g\n",
24+ data.data[0], data.data[1], data.data[2], data.data[3],
25+ data.d1, data.d2);
26+}
27+
28+int main(void) {
29+ /* This code resulted in a bounds checking error */
30+ Node data;
31+ dummy (data);
32+ char val;
33+ data = init (data);
34+ print_data(data);
35+}
tests/tests2/121_struct_return.expect+1−0
@@ -0,0 +1 @@
1+0 1 2 3 1234 2345
tests/tests2/122_vla_reuse.c+31−0
@@ -0,0 +1,31 @@
1+#include <stdio.h>
2+
3+int
4+main (void)
5+{
6+ int n = 0;
7+ int first=1;
8+ int *p[101];
9+ if (0) {
10+ lab:;
11+ }
12+ int x[n % 100 + 1];
13+ if (first == 0) {
14+ if (&x[0] != p[n % 100 + 1]) {
15+ printf ("ERROR: %d %p $p\n", &x[0], p[n % 100 + 1]);
16+ return(1);
17+ }
18+ }
19+ else {
20+ p[n % 100 + 1] = &x[0];
21+ first = n < 100;
22+ }
23+ x[0] = 1;
24+ x[n % 100] = 2;
25+ n++;
26+ if (n < 100000)
27+ goto lab;
28+ printf ("OK\n");
29+ return 0;
30+}
31+
tests/tests2/122_vla_reuse.expect+1−0
@@ -0,0 +1 @@
1+OK
tests/tests2/Makefile+2−0
@@ -103,6 +103,8 @@ GEN-ALWAYS = · 102 unmodified lines
103103 115_bound_setjmp.test: FLAGS += -b
104104 116_bound_setjmp2.test: FLAGS += -b
105105 117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 )
106+121_struct_return.test: FLAGS += -b
107+122_vla_reuse.test: FLAGS += -b
106108
107109 # Filter source directory in warnings/errors (out-of-tree builds)
108110 FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'

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