History

Add sigsetjmp/siglongjmp bound checking support

tcctok.h: - Add sigsetjmp/__sigsetjmp/siglongjmp tccgen.c: - redirect sigsetjmp/siglongjmp to bcheck.c code i386-gen.c/x86_64-gen.c - gcall_or_jmp: Set func_bound_add_epilog also when sigsetjmp is called - gen_bounds_epilog: Only call __bound_local_new when needed (unrelated) bcheck.c: - Add __bound_siglongjmp - __bound_setjmp/__bound_long_jump: Check no_checking - Optimize __bound_local_delete (unrelated) Modify testcase: - 114_bound_signal

herman ten brugge committed 6 years ago

Commit 3b617fd1 parent 045632d6 files · +182 −131Browse files

Unified · Split

6 files
  1. i386-gen.c +16 −8
  2. lib/bcheck.c +120 −114
  3. tccgen.c +9 −1
  4. tcctok.h +4 −0
  5. tests/tests2/114_bound_signal.c +17 −0
  6. x86_64-gen.c +16 −8
i386-gen.c+16−8
@@ -363,7 +363,12 @@ static void gcall_or_jmp(int is_jmp) · 362 unmodified lines
363363 if (tcc_state->do_bounds_check &&
364364 (vtop->sym->v == TOK_alloca ||
365365 vtop->sym->v == TOK_setjmp ||
366− vtop->sym->v == TOK__setjmp))
366+ vtop->sym->v == TOK__setjmp
367+#ifndef TCC_TARGET_PE
368+ || vtop->sym->v == TOK_sigsetjmp
369+ || vtop->sym->v == TOK___sigsetjmp
370+#endif
371+ ))
367372 func_bound_add_epilog = 1;
368373 #endif
369374 } else {
@@ -1092,15 +1097,18 @@ static void gen_bounds_epilog(void) · 722 unmodified lines
10921097 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
10931098 *bounds_ptr = 0;
10941099
1095− /* generate bound local allocation */
1096− saved_ind = ind;
1097− ind = func_bound_ind;
10981100 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
10991101 func_bound_offset, lbounds_section->data_offset);
1100− greloc(cur_text_section, sym_data, ind + 1, R_386_32);
1101− ind = ind + 5;
1102− gen_static_call(TOK___bound_local_new);
1103− ind = saved_ind;
1102+
1103+ /* generate bound local allocation */
1104+ if (func_bound_offset != lbounds_section->data_offset) {
1105+ saved_ind = ind;
1106+ ind = func_bound_ind;
1107+ greloc(cur_text_section, sym_data, ind + 1, R_386_32);
1108+ ind = ind + 5;
1109+ gen_static_call(TOK___bound_local_new);
1110+ ind = saved_ind;
1111+ }
11041112
11051113 /* generate bound check local freeing */
11061114 o(0x5250); /* save returned value, if any */
lib/bcheck.c+120−114
@@ -205,6 +205,7 @@ void __bound_exit(void); · 204 unmodified lines
205205 void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,
206206 off_t offset);
207207 int __bound_munmap (void *start, size_t size);
208+DLL_EXPORT void __bound_siglongjmp(jmp_buf env, int val);
208209 #endif
209210 DLL_EXPORT void __bound_new_region(void *p, size_t size);
210211 DLL_EXPORT void __bound_setjmp(jmp_buf env);
@@ -510,8 +511,6 @@ void FASTCALL __bound_local_new(void *p1) · 299 unmodified lines
510511 void FASTCALL __bound_local_delete(void *p1)
511512 {
512513 size_t addr, fp, *p = p1;
513− alloca_list_type *alloca_free_list = NULL;
514− jmp_list_type *jmp_free_list = NULL;
515514
516515 if (no_checking)
517516 return;
@@ -524,65 +523,51 @@ void FASTCALL __bound_local_delete(void *p1) · 6 unmodified lines
524523 tree = splay_delete(addr + fp, tree);
525524 p += 2;
526525 }
527− {
526+ if (alloca_list) {
528527 alloca_list_type *last = NULL;
529528 alloca_list_type *cur = alloca_list;
530529
531− while (cur) {
530+ do {
532531 if (cur->fp == fp) {
533532 if (last)
534533 last->next = cur->next;
535534 else
536535 alloca_list = cur->next;
537536 tree = splay_delete ((size_t) cur->p, tree);
538− cur->next = alloca_free_list;
539− alloca_free_list = cur;
537+ dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
538+ __FILE__, __FUNCTION__, cur->p);
539+ BOUND_FREE (cur);
540540 cur = last ? last->next : alloca_list;
541541 }
542542 else {
543543 last = cur;
544544 cur = cur->next;
545545 }
546− }
546+ } while (cur);
547547 }
548− {
548+ if (jmp_list) {
549549 jmp_list_type *last = NULL;
550550 jmp_list_type *cur = jmp_list;
551551
552− while (cur) {
552+ do {
553553 if (cur->fp == fp) {
554554 if (last)
555555 last->next = cur->next;
556556 else
557557 jmp_list = cur->next;
558− cur->next = jmp_free_list;
559− jmp_free_list = cur;
558+ dprintf(stderr, "%s, %s(): remove setjmp %p\n",
559+ __FILE__, __FUNCTION__, cur->penv);
560+ BOUND_FREE (cur);
560561 cur = last ? last->next : jmp_list;
561562 }
562563 else {
563564 last = cur;
564565 cur = cur->next;
565566 }
566− }
567+ } while (cur);
567568 }
568569
569570 POST_SEM ();
570− while (alloca_free_list) {
571− alloca_list_type *next = alloca_free_list->next;
572−
573− dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
574− __FILE__, __FUNCTION__, alloca_free_list->p);
575− BOUND_FREE (alloca_free_list);
576− alloca_free_list = next;
577− }
578− while (jmp_free_list) {
579− jmp_list_type *next = jmp_free_list->next;
580−
581− dprintf(stderr, "%s, %s(): remove setjmp %p\n",
582− __FILE__, __FUNCTION__, jmp_free_list->penv);
583− BOUND_FREE (jmp_free_list);
584− jmp_free_list = next;
585− }
586571 #if BOUND_DEBUG
587572 if (print_calls) {
588573 p = p1;
@@ -647,107 +632,128 @@ void __bound_setjmp(jmp_buf env) · 58 unmodified lines
647632 jmp_list_type *jl;
648633 void *e = (void *) env;
649634
650− dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
651− WAIT_SEM ();
652− INCR_COUNT(bound_setjmp_count);
653− jl = jmp_list;
654− while (jl) {
655− if (jl->penv == e)
656− break;
657− jl = jl->next;
658− }
659− if (jl == NULL) {
660− jl = BOUND_MALLOC (sizeof (jmp_list_type));
661− if (jl) {
662− jl->penv = e;
663− jl->next = jmp_list;
664− jmp_list = jl;
635+ if (no_checking == 0) {
636+ dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
637+ WAIT_SEM ();
638+ INCR_COUNT(bound_setjmp_count);
639+ jl = jmp_list;
640+ while (jl) {
641+ if (jl->penv == e)
642+ break;
643+ jl = jl->next;
665644 }
666− }
667− if (jl) {
668− size_t fp;
645+ if (jl == NULL) {
646+ jl = BOUND_MALLOC (sizeof (jmp_list_type));
647+ if (jl) {
648+ jl->penv = e;
649+ jl->next = jmp_list;
650+ jmp_list = jl;
651+ }
652+ }
653+ if (jl) {
654+ size_t fp;
669655
670− GET_CALLER_FP (fp);
671− jl->fp = fp;
672− jl->end_fp = (size_t)__builtin_frame_address(0);
673− jl->tid = BOUND_GET_TID;
656+ GET_CALLER_FP (fp);
657+ jl->fp = fp;
658+ jl->end_fp = (size_t)__builtin_frame_address(0);
659+ jl->tid = BOUND_GET_TID;
660+ }
661+ POST_SEM ();
674662 }
675− POST_SEM ();
676663 }
677664
678−void __bound_longjmp(jmp_buf env, int val)
665+static void __bound_long_jump(jmp_buf env, int val, int sig, const char *func)
679666 {
680667 jmp_list_type *jl;
681− void *e = (void *)env;
682− BOUND_TID_TYPE tid = BOUND_GET_TID;
683−
684− dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
685− WAIT_SEM();
686− INCR_COUNT(bound_longjmp_count);
687− jl = jmp_list;
688− while (jl) {
689− if (jl->penv == e && jl->tid == tid) {
690− size_t start_fp = (size_t)__builtin_frame_address(0);
691− size_t end_fp = jl->end_fp;
692− jmp_list_type *cur = jmp_list;
693− jmp_list_type *last = NULL;
694−
695− while (cur->penv != e || cur->tid != tid) {
696− if (cur->tid == tid) {
697− dprintf(stderr, "%s, %s(): remove setjmp %p\n",
698− __FILE__, __FUNCTION__, cur->penv);
699− if (last)
700− last->next = cur->next;
701− else
702− jmp_list = cur->next;
703− BOUND_FREE (cur);
704− cur = last ? last->next : jmp_list;
705− }
706− else {
707− last = cur;
708− cur = cur->next;
668+ void *e;
669+ BOUND_TID_TYPE tid;
670+
671+ if (no_checking == 0) {
672+ e = (void *)env;
673+ tid = BOUND_GET_TID;
674+ dprintf(stderr, "%s, %s(): %p\n", __FILE__, func, e);
675+ WAIT_SEM();
676+ INCR_COUNT(bound_longjmp_count);
677+ jl = jmp_list;
678+ while (jl) {
679+ if (jl->penv == e && jl->tid == tid) {
680+ size_t start_fp = (size_t)__builtin_frame_address(0);
681+ size_t end_fp = jl->end_fp;
682+ jmp_list_type *cur = jmp_list;
683+ jmp_list_type *last = NULL;
684+
685+ while (cur->penv != e || cur->tid != tid) {
686+ if (cur->tid == tid) {
687+ dprintf(stderr, "%s, %s(): remove setjmp %p\n",
688+ __FILE__, func, cur->penv);
689+ if (last)
690+ last->next = cur->next;
691+ else
692+ jmp_list = cur->next;
693+ BOUND_FREE (cur);
694+ cur = last ? last->next : jmp_list;
695+ }
696+ else {
697+ last = cur;
698+ cur = cur->next;
699+ }
709700 }
710− }
711− for (;;) {
712− Tree *t = tree;
713− alloca_list_type *last;
714− alloca_list_type *cur;
715−
716− while (t && (t->start < start_fp || t->start > end_fp))
717− if (t->start < start_fp)
718− t = t->right;
719− else
720− t = t->left;
721− if (t == NULL)
722− break;
723− last = NULL;
724− cur = alloca_list;
725− while (cur) {
726− if ((size_t) cur->p == t->start) {
727− dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
728− __FILE__, __FUNCTION__, cur->p);
729− if (last)
730− last->next = cur->next;
731− else
732− alloca_list = cur->next;
733− BOUND_FREE (cur);
734− break;
735− }
736− last = cur;
737− cur = cur->next;
701+ for (;;) {
702+ Tree *t = tree;
703+ alloca_list_type *last;
704+ alloca_list_type *cur;
705+
706+ while (t && (t->start < start_fp || t->start > end_fp))
707+ if (t->start < start_fp)
708+ t = t->right;
709+ else
710+ t = t->left;
711+ if (t == NULL)
712+ break;
713+ last = NULL;
714+ cur = alloca_list;
715+ while (cur) {
716+ if ((size_t) cur->p == t->start) {
717+ dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
718+ __FILE__, func, cur->p);
719+ if (last)
720+ last->next = cur->next;
721+ else
722+ alloca_list = cur->next;
723+ BOUND_FREE (cur);
724+ break;
725+ }
726+ last = cur;
727+ cur = cur->next;
728+ }
729+ dprintf(stderr, "%s, %s(): delete %p\n",
730+ __FILE__, func, (void *) t->start);
731+ tree = splay_delete(t->start, tree);
738732 }
739− dprintf(stderr, "%s, %s(): delete %p\n",
740− __FILE__, __FUNCTION__, (void *) t->start);
741− tree = splay_delete(t->start, tree);
733+ break;
742734 }
743− break;
735+ jl = jl->next;
744736 }
745− jl = jl->next;
737+ POST_SEM();
746738 }
747− POST_SEM();
739+#if !defined(_WIN32)
740+ sig ? siglongjmp(env, val) :
741+#endif
748742 longjmp (env, val);
749743 }
750744
745+void __bound_longjmp(jmp_buf env, int val)
746+{
747+ __bound_long_jump(env,val, 0, __FUNCTION__);
748+}
749+
750+#if !defined(_WIN32)
751+void __bound_siglongjmp(jmp_buf env, int val)
752+{
753+ __bound_long_jump(env,val, 1, __FUNCTION__);
754+}
755+#endif
756+
751757 #if defined(__GNUC__) && (__GNUC__ >= 6)
752758 #pragma GCC diagnostic pop
753759 #endif
tccgen.c+9−1
@@ -911,6 +911,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 910 unmodified lines
911911 case TOK_mmap:
912912 case TOK_munmap:
913913 case TOK_longjmp:
914+#ifndef TCC_TARGET_PE
915+ case TOK_siglongjmp:
916+#endif
914917 strcpy(buf, "__bound_");
915918 strcat(buf, name);
916919 name = buf;
@@ -6018,7 +6021,12 @@ special_math_val: · 5101 unmodified lines
60186021 (nb_args == 1 || nb_args == 2) &&
60196022 (vtop[-nb_args].r & VT_SYM) &&
60206023 (vtop[-nb_args].sym->v == TOK_setjmp ||
6021− vtop[-nb_args].sym->v == TOK__setjmp)) {
6024+ vtop[-nb_args].sym->v == TOK__setjmp
6025+#ifndef TCC_TARGET_PE
6026+ || vtop[-nb_args].sym->v == TOK_sigsetjmp
6027+ || vtop[-nb_args].sym->v == TOK___sigsetjmp
6028+#endif
6029+ )) {
60226030 vpush_global_sym(&func_old_type, TOK___bound_setjmp);
60236031 vpushv(vtop - nb_args);
60246032 if (nb_args == 2)
tcctok.h+4−0
@@ -315,6 +315,10 @@ · 314 unmodified lines
315315 DEF(TOK_realloc, "realloc")
316316 DEF(TOK_memalign, "memalign")
317317 DEF(TOK_calloc, "calloc")
318+# else
319+ DEF(TOK_sigsetjmp, "sigsetjmp")
320+ DEF(TOK___sigsetjmp, "__sigsetjmp")
321+ DEF(TOK_siglongjmp, "siglongjmp")
318322 # endif
319323 DEF(TOK_mmap, "mmap")
320324 DEF(TOK_munmap, "munmap")
tests/tests2/114_bound_signal.c+17−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <sys/types.h>
77 #include <unistd.h>
88 #include <errno.h>
9+#include <setjmp.h>
910
1011 static volatile int run = 1;
1112 static int dummy[10];
@@ -70,6 +71,8 @@ main (void) · 58 unmodified lines
7071 pthread_t id1, id2;
7172 struct sigaction act;
7273 struct timespec request;
74+ sigjmp_buf sj;
75+ sigset_t m;
7376
7477 memset (&act, 0, sizeof (act));
7578 act.sa_handler = signal_handler;
@@ -90,5 +93,19 @@ main (void) · 14 unmodified lines
9093 pthread_join(id1, NULL);
9194 pthread_join(id2, NULL);
9295 sem_destroy (&sem);
96+
97+ sigemptyset (&m);
98+ sigprocmask (SIG_SETMASK, &m, NULL);
99+ if (sigsetjmp (sj, 0) == 0)
100+ {
101+ sigaddset (&m, SIGUSR1);
102+ sigprocmask (SIG_SETMASK, &m, NULL);
103+ siglongjmp (sj, 1);
104+ printf ("failed");
105+ return 1;
106+ }
107+ sigprocmask (SIG_SETMASK, NULL, &m);
108+ if (!sigismember (&m, SIGUSR1))
109+ printf ("failed");
93110 return 0;
94111 }
x86_64-gen.c+16−8
@@ -640,7 +640,12 @@ static void gcall_or_jmp(int is_jmp) · 639 unmodified lines
640640 if (tcc_state->do_bounds_check &&
641641 (vtop->sym->v == TOK_alloca ||
642642 vtop->sym->v == TOK_setjmp ||
643− vtop->sym->v == TOK__setjmp))
643+ vtop->sym->v == TOK__setjmp
644+#ifndef TCC_TARGET_PE
645+ || vtop->sym->v == TOK_sigsetjmp
646+ || vtop->sym->v == TOK___sigsetjmp
647+#endif
648+ ))
644649 func_bound_add_epilog = 1;
645650 #endif
646651 } else {
@@ -747,15 +752,18 @@ static void gen_bounds_epilog(void) · 100 unmodified lines
747752 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
748753 *bounds_ptr = 0;
749754
750− /* generate bound local allocation */
751755 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
752756 func_bound_offset, lbounds_section->data_offset);
753− saved_ind = ind;
754− ind = func_bound_ind;
755− greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
756− ind = ind + 10;
757− gen_bounds_call(TOK___bound_local_new);
758− ind = saved_ind;
757+
758+ /* generate bound local allocation */
759+ if (func_bound_offset != lbounds_section->data_offset) {
760+ saved_ind = ind;
761+ ind = func_bound_ind;
762+ greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
763+ ind = ind + 10;
764+ gen_bounds_call(TOK___bound_local_new);
765+ ind = saved_ind;
766+ }
759767
760768 /* generate bound check local freeing */
761769 o(0x5250); /* save returned value, if any */

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