From: Tom Hughes Date: Sat, 11 Sep 2004 14:16:57 +0000 (+0000) Subject: Virtualise the stack rlimit for the main thread and make valgrind enforce X-Git-Tag: svn/VALGRIND_3_0_0~1596 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2aad0526df2e695f14d92ba0e6d932689adb01b5;p=thirdparty%2Fvalgrind.git Virtualise the stack rlimit for the main thread and make valgrind enforce that limit when growing the stack. Also add a message when the stack in any thread overflows. CCMAIL: 73818-done@bugs.kde.org git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2689 --- diff --git a/coregrind/core.h b/coregrind/core.h index deff8721f5..2a99c42f50 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -1243,6 +1243,7 @@ extern Addr VG_(valgrind_base); /* valgrind's address range */ extern Addr VG_(valgrind_last); // Nb: last byte, rather than one past the end extern vki_rlimit VG_(client_rlimit_data); /* client's original rlimit data */ +extern vki_rlimit VG_(client_rlimit_stack); /* client's original rlimit stack */ /* client executable file descriptor */ extern Int VG_(clexecfd); diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 183fa2ea1a..a077d58c0d 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -113,6 +113,7 @@ Addr VG_(valgrind_base); /* valgrind's address range */ Addr VG_(valgrind_last); vki_rlimit VG_(client_rlimit_data); +vki_rlimit VG_(client_rlimit_stack); /* This is set early to indicate whether this CPU has the SSE/fxsave/fxrestor features. */ @@ -2496,7 +2497,10 @@ int main(int argc, char **argv) VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); zero.rlim_max = VG_(client_rlimit_data).rlim_max; VG_(setrlimit)(VKI_RLIMIT_DATA, &zero); - + + // Get the current process stack rlimit. + VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack)); + //-------------------------------------------------------------- // Check we were launched by stage1 // p: n/a diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index b181746138..cf4050c7b9 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -394,7 +394,7 @@ void mostly_clear_thread_record ( ThreadId tid ) */ void VG_(scheduler_init) ( void ) { - Int i; + Int i; ThreadId tid_main; for (i = 0 /* NB; not 1 */; i < VG_N_THREADS; i++) { @@ -428,7 +428,7 @@ void VG_(scheduler_init) ( void ) VG_(threads)[tid_main].stack_highest_word = VG_(clstk_end) - 4; VG_(threads)[tid_main].stack_base = VG_(clstk_base); - VG_(threads)[tid_main].stack_size = VG_(clstk_end) - VG_(clstk_base); + VG_(threads)[tid_main].stack_size = VG_(client_rlimit_stack).rlim_cur; /* So now ... */ vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID); diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 4f4061b288..9a8ace72e7 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -2109,7 +2109,8 @@ void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontex then extend the stack segment. */ Addr base = PGROUNDDN(esp); - if ((void*)-1 != VG_(mmap)((Char *)base, seg->addr - base, + if (seg->len + (seg->addr - base) <= VG_(threads)[tid].stack_size && + (void*)-1 != VG_(mmap)((Char *)base, seg->addr - base, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, VKI_MAP_PRIVATE|VKI_MAP_FIXED|VKI_MAP_ANONYMOUS|VKI_MAP_CLIENT, SF_STACK|SF_GROWDOWN, @@ -2138,6 +2139,14 @@ void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontex recursion--; } } + + if (info->si_code == 1 && /* SEGV_MAPERR */ + seg != NULL && + fault >= esp && + fault < seg->addr && + (seg->flags & SF_STACK)) { + VG_(message)(Vg_UserMsg, "Stack overflow in thread %d", tid); + } } /* Can't continue; must longjmp back to the scheduler and thus diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 2934f40e45..14ea259c99 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -2346,6 +2346,10 @@ POST(getrlimit) case VKI_RLIMIT_DATA: *((vki_rlimit *)arg2) = VG_(client_rlimit_data); break; + + case VKI_RLIMIT_STACK: + *((vki_rlimit *)arg2) = VG_(client_rlimit_stack); + break; } } @@ -4692,6 +4696,17 @@ PRE(setrlimit) VG_(client_rlimit_data) = *(vki_rlimit *)arg2; res = 0; } + else if (arg1 == VKI_RLIMIT_STACK && tid == 1) { + if (((vki_rlimit *)arg2)->rlim_cur > ((vki_rlimit *)arg2)->rlim_max || + ((vki_rlimit *)arg2)->rlim_max > ((vki_rlimit *)arg2)->rlim_max) { + res = -VKI_EPERM; + } + else { + VG_(threads)[tid].stack_size = ((vki_rlimit *)arg2)->rlim_cur; + VG_(client_rlimit_stack) = *(vki_rlimit *)arg2; + res = 0; + } + } } PRE(setuid)