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
363 if (tcc_state->do_bounds_check &&363 if (tcc_state->do_bounds_check &&
364 (vtop->sym->v == TOK_alloca ||364 (vtop->sym->v == TOK_alloca ||
365 vtop->sym->v == TOK_setjmp ||365 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 ))
367 func_bound_add_epilog = 1;372 func_bound_add_epilog = 1;
368#endif373#endif
369 } else {374 } else {
@@ -1092,15 +1097,18 @@ static void gen_bounds_epilog(void) · 722 unmodified lines
1092 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));1097 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
1093 *bounds_ptr = 0;1098 *bounds_ptr = 0;
1094 1099
1095 /* generate bound local allocation */
1096 saved_ind = ind;
1097 ind = func_bound_ind;
1098 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,1100 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
1099 func_bound_offset, lbounds_section->data_offset);1101 func_bound_offset, lbounds_section->data_offset);
1100 greloc(cur_text_section, sym_data, ind + 1, R_386_32);1102
1101 ind = ind + 5;1103 /* generate bound local allocation */
1102 gen_static_call(TOK___bound_local_new);1104 if (func_bound_offset != lbounds_section->data_offset) {
1103 ind = saved_ind;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 }
1104 1112
1105 /* generate bound check local freeing */1113 /* generate bound check local freeing */
1106 o(0x5250); /* save returned value, if any */1114 o(0x5250); /* save returned value, if any */
lib/bcheck.c+120−114
@@ -205,6 +205,7 @@ void __bound_exit(void); · 204 unmodified lines
205void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,205void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,
206 off_t offset);206 off_t offset);
207int __bound_munmap (void *start, size_t size);207int __bound_munmap (void *start, size_t size);
208DLL_EXPORT void __bound_siglongjmp(jmp_buf env, int val);
208#endif209#endif
209DLL_EXPORT void __bound_new_region(void *p, size_t size);210DLL_EXPORT void __bound_new_region(void *p, size_t size);
210DLL_EXPORT void __bound_setjmp(jmp_buf env);211DLL_EXPORT void __bound_setjmp(jmp_buf env);
@@ -510,8 +511,6 @@ void FASTCALL __bound_local_new(void *p1) · 299 unmodified lines
510void FASTCALL __bound_local_delete(void *p1) 511void FASTCALL __bound_local_delete(void *p1)
511{512{
512 size_t addr, fp, *p = p1;513 size_t addr, fp, *p = p1;
513 alloca_list_type *alloca_free_list = NULL;
514 jmp_list_type *jmp_free_list = NULL;
515 514
516 if (no_checking)515 if (no_checking)
517 return;516 return;
@@ -524,65 +523,51 @@ void FASTCALL __bound_local_delete(void *p1) · 6 unmodified lines
524 tree = splay_delete(addr + fp, tree);523 tree = splay_delete(addr + fp, tree);
525 p += 2;524 p += 2;
526 }525 }
527 {526 if (alloca_list) {
528 alloca_list_type *last = NULL;527 alloca_list_type *last = NULL;
529 alloca_list_type *cur = alloca_list;528 alloca_list_type *cur = alloca_list;
530 529
531 while (cur) {530 do {
532 if (cur->fp == fp) {531 if (cur->fp == fp) {
533 if (last)532 if (last)
534 last->next = cur->next;533 last->next = cur->next;
535 else534 else
536 alloca_list = cur->next;535 alloca_list = cur->next;
537 tree = splay_delete ((size_t) cur->p, tree);536 tree = splay_delete ((size_t) cur->p, tree);
538 cur->next = alloca_free_list;537 dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
539 alloca_free_list = cur;538 __FILE__, __FUNCTION__, cur->p);
539 BOUND_FREE (cur);
540 cur = last ? last->next : alloca_list;540 cur = last ? last->next : alloca_list;
541 }541 }
542 else {542 else {
543 last = cur;543 last = cur;
544 cur = cur->next;544 cur = cur->next;
545 }545 }
546 }546 } while (cur);
547 }547 }
548 {548 if (jmp_list) {
549 jmp_list_type *last = NULL;549 jmp_list_type *last = NULL;
550 jmp_list_type *cur = jmp_list;550 jmp_list_type *cur = jmp_list;
551 551
552 while (cur) {552 do {
553 if (cur->fp == fp) {553 if (cur->fp == fp) {
554 if (last)554 if (last)
555 last->next = cur->next;555 last->next = cur->next;
556 else556 else
557 jmp_list = cur->next;557 jmp_list = cur->next;
558 cur->next = jmp_free_list;558 dprintf(stderr, "%s, %s(): remove setjmp %p\n",
559 jmp_free_list = cur;559 __FILE__, __FUNCTION__, cur->penv);
560 BOUND_FREE (cur);
560 cur = last ? last->next : jmp_list;561 cur = last ? last->next : jmp_list;
561 }562 }
562 else {563 else {
563 last = cur;564 last = cur;
564 cur = cur->next;565 cur = cur->next;
565 }566 }
566 }567 } while (cur);
567 }568 }
568 569
569 POST_SEM ();570 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 }
586#if BOUND_DEBUG571#if BOUND_DEBUG
587 if (print_calls) {572 if (print_calls) {
588 p = p1;573 p = p1;
@@ -647,107 +632,128 @@ void __bound_setjmp(jmp_buf env) · 58 unmodified lines
647 jmp_list_type *jl;632 jmp_list_type *jl;
648 void *e = (void *) env;633 void *e = (void *) env;
649 634
650 dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);635 if (no_checking == 0) {
651 WAIT_SEM ();636 dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
652 INCR_COUNT(bound_setjmp_count);637 WAIT_SEM ();
653 jl = jmp_list;638 INCR_COUNT(bound_setjmp_count);
654 while (jl) {639 jl = jmp_list;
655 if (jl->penv == e)640 while (jl) {
656 break;641 if (jl->penv == e)
657 jl = jl->next;642 break;
658 }643 jl = jl->next;
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;
665 }644 }
666 }645 if (jl == NULL) {
667 if (jl) {646 jl = BOUND_MALLOC (sizeof (jmp_list_type));
668 size_t fp;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;
669 655
670 GET_CALLER_FP (fp);656 GET_CALLER_FP (fp);
671 jl->fp = fp;657 jl->fp = fp;
672 jl->end_fp = (size_t)__builtin_frame_address(0);658 jl->end_fp = (size_t)__builtin_frame_address(0);
673 jl->tid = BOUND_GET_TID;659 jl->tid = BOUND_GET_TID;
660 }
661 POST_SEM ();
674 }662 }
675 POST_SEM ();
676}663}
677 664
678void __bound_longjmp(jmp_buf env, int val)665static void __bound_long_jump(jmp_buf env, int val, int sig, const char *func)
679{666{
680 jmp_list_type *jl;667 jmp_list_type *jl;
681 void *e = (void *)env;668 void *e;
682 BOUND_TID_TYPE tid = BOUND_GET_TID;669 BOUND_TID_TYPE tid;
683 670
684 dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);671 if (no_checking == 0) {
685 WAIT_SEM();672 e = (void *)env;
686 INCR_COUNT(bound_longjmp_count);673 tid = BOUND_GET_TID;
687 jl = jmp_list;674 dprintf(stderr, "%s, %s(): %p\n", __FILE__, func, e);
688 while (jl) {675 WAIT_SEM();
689 if (jl->penv == e && jl->tid == tid) {676 INCR_COUNT(bound_longjmp_count);
690 size_t start_fp = (size_t)__builtin_frame_address(0);677 jl = jmp_list;
691 size_t end_fp = jl->end_fp;678 while (jl) {
692 jmp_list_type *cur = jmp_list;679 if (jl->penv == e && jl->tid == tid) {
693 jmp_list_type *last = NULL;680 size_t start_fp = (size_t)__builtin_frame_address(0);
694 681 size_t end_fp = jl->end_fp;
695 while (cur->penv != e || cur->tid != tid) {682 jmp_list_type *cur = jmp_list;
696 if (cur->tid == tid) {683 jmp_list_type *last = NULL;
697 dprintf(stderr, "%s, %s(): remove setjmp %p\n",684
698 __FILE__, __FUNCTION__, cur->penv);685 while (cur->penv != e || cur->tid != tid) {
699 if (last)686 if (cur->tid == tid) {
700 last->next = cur->next;687 dprintf(stderr, "%s, %s(): remove setjmp %p\n",
701 else688 __FILE__, func, cur->penv);
702 jmp_list = cur->next;689 if (last)
703 BOUND_FREE (cur);690 last->next = cur->next;
704 cur = last ? last->next : jmp_list;691 else
705 }692 jmp_list = cur->next;
706 else {693 BOUND_FREE (cur);
707 last = cur;694 cur = last ? last->next : jmp_list;
708 cur = cur->next;695 }
696 else {
697 last = cur;
698 cur = cur->next;
699 }
709 }700 }
710 }701 for (;;) {
711 for (;;) {702 Tree *t = tree;
712 Tree *t = tree;703 alloca_list_type *last;
713 alloca_list_type *last;704 alloca_list_type *cur;
714 alloca_list_type *cur;705
715 706 while (t && (t->start < start_fp || t->start > end_fp))
716 while (t && (t->start < start_fp || t->start > end_fp))707 if (t->start < start_fp)
717 if (t->start < start_fp)708 t = t->right;
718 t = t->right;709 else
719 else710 t = t->left;
720 t = t->left;711 if (t == NULL)
721 if (t == NULL)712 break;
722 break;713 last = NULL;
723 last = NULL;714 cur = alloca_list;
724 cur = alloca_list;715 while (cur) {
725 while (cur) {716 if ((size_t) cur->p == t->start) {
726 if ((size_t) cur->p == t->start) {717 dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
727 dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",718 __FILE__, func, cur->p);
728 __FILE__, __FUNCTION__, cur->p);719 if (last)
729 if (last)720 last->next = cur->next;
730 last->next = cur->next;721 else
731 else722 alloca_list = cur->next;
732 alloca_list = cur->next;723 BOUND_FREE (cur);
733 BOUND_FREE (cur);724 break;
734 break;725 }
735 }726 last = cur;
736 last = cur;727 cur = cur->next;
737 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);
738 }732 }
739 dprintf(stderr, "%s, %s(): delete %p\n",733 break;
740 __FILE__, __FUNCTION__, (void *) t->start);
741 tree = splay_delete(t->start, tree);
742 }734 }
743 break;735 jl = jl->next;
744 }736 }
745 jl = jl->next;737 POST_SEM();
746 }738 }
747 POST_SEM();739#if !defined(_WIN32)
740 sig ? siglongjmp(env, val) :
741#endif
748 longjmp (env, val);742 longjmp (env, val);
749}743}
750 744
745void __bound_longjmp(jmp_buf env, int val)
746{
747 __bound_long_jump(env,val, 0, __FUNCTION__);
748}
749
750#if !defined(_WIN32)
751void __bound_siglongjmp(jmp_buf env, int val)
752{
753 __bound_long_jump(env,val, 1, __FUNCTION__);
754}
755#endif
756
751#if defined(__GNUC__) && (__GNUC__ >= 6)757#if defined(__GNUC__) && (__GNUC__ >= 6)
752#pragma GCC diagnostic pop758#pragma GCC diagnostic pop
753#endif759#endif
tccgen.c+9−1
@@ -911,6 +911,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 910 unmodified lines
911 case TOK_mmap:911 case TOK_mmap:
912 case TOK_munmap:912 case TOK_munmap:
913 case TOK_longjmp:913 case TOK_longjmp:
914#ifndef TCC_TARGET_PE
915 case TOK_siglongjmp:
916#endif
914 strcpy(buf, "__bound_");917 strcpy(buf, "__bound_");
915 strcat(buf, name);918 strcat(buf, name);
916 name = buf;919 name = buf;
@@ -6018,7 +6021,12 @@ special_math_val: · 5101 unmodified lines
6018 (nb_args == 1 || nb_args == 2) &&6021 (nb_args == 1 || nb_args == 2) &&
6019 (vtop[-nb_args].r & VT_SYM) &&6022 (vtop[-nb_args].r & VT_SYM) &&
6020 (vtop[-nb_args].sym->v == TOK_setjmp ||6023 (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 )) {
6022 vpush_global_sym(&func_old_type, TOK___bound_setjmp);6030 vpush_global_sym(&func_old_type, TOK___bound_setjmp);
6023 vpushv(vtop - nb_args);6031 vpushv(vtop - nb_args);
6024 if (nb_args == 2)6032 if (nb_args == 2)
tcctok.h+4−0
@@ -315,6 +315,10 @@ · 314 unmodified lines
315 DEF(TOK_realloc, "realloc")315 DEF(TOK_realloc, "realloc")
316 DEF(TOK_memalign, "memalign")316 DEF(TOK_memalign, "memalign")
317 DEF(TOK_calloc, "calloc")317 DEF(TOK_calloc, "calloc")
318# else
319 DEF(TOK_sigsetjmp, "sigsetjmp")
320 DEF(TOK___sigsetjmp, "__sigsetjmp")
321 DEF(TOK_siglongjmp, "siglongjmp")
318# endif322# endif
319 DEF(TOK_mmap, "mmap")323 DEF(TOK_mmap, "mmap")
320 DEF(TOK_munmap, "munmap")324 DEF(TOK_munmap, "munmap")
tests/tests2/114_bound_signal.c+17−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include <sys/types.h>6#include <sys/types.h>
7#include <unistd.h>7#include <unistd.h>
8#include <errno.h>8#include <errno.h>
9#include <setjmp.h>
9 10
10static volatile int run = 1;11static volatile int run = 1;
11static int dummy[10];12static int dummy[10];
@@ -70,6 +71,8 @@ main (void) · 58 unmodified lines
70 pthread_t id1, id2;71 pthread_t id1, id2;
71 struct sigaction act;72 struct sigaction act;
72 struct timespec request;73 struct timespec request;
74 sigjmp_buf sj;
75 sigset_t m;
73 76
74 memset (&act, 0, sizeof (act));77 memset (&act, 0, sizeof (act));
75 act.sa_handler = signal_handler;78 act.sa_handler = signal_handler;
@@ -90,5 +93,19 @@ main (void) · 14 unmodified lines
90 pthread_join(id1, NULL);93 pthread_join(id1, NULL);
91 pthread_join(id2, NULL);94 pthread_join(id2, NULL);
92 sem_destroy (&sem);95 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");
93 return 0;110 return 0;
94}111}
x86_64-gen.c+16−8
@@ -640,7 +640,12 @@ static void gcall_or_jmp(int is_jmp) · 639 unmodified lines
640 if (tcc_state->do_bounds_check &&640 if (tcc_state->do_bounds_check &&
641 (vtop->sym->v == TOK_alloca ||641 (vtop->sym->v == TOK_alloca ||
642 vtop->sym->v == TOK_setjmp ||642 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 ))
644 func_bound_add_epilog = 1;649 func_bound_add_epilog = 1;
645#endif650#endif
646 } else {651 } else {
@@ -747,15 +752,18 @@ static void gen_bounds_epilog(void) · 100 unmodified lines
747 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));752 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
748 *bounds_ptr = 0;753 *bounds_ptr = 0;
749 754
750 /* generate bound local allocation */
751 sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 755 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
752 func_bound_offset, lbounds_section->data_offset);756 func_bound_offset, lbounds_section->data_offset);
753 saved_ind = ind;757
754 ind = func_bound_ind;758 /* generate bound local allocation */
755 greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);759 if (func_bound_offset != lbounds_section->data_offset) {
756 ind = ind + 10;760 saved_ind = ind;
757 gen_bounds_call(TOK___bound_local_new);761 ind = func_bound_ind;
758 ind = saved_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 }
759 767
760 /* generate bound check local freeing */768 /* generate bound check local freeing */
761 o(0x5250); /* save returned value, if any */769 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