]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Virtualise the stack rlimit for the main thread and make valgrind enforce
authorTom Hughes <tom@compton.nu>
Sat, 11 Sep 2004 14:16:57 +0000 (14:16 +0000)
committerTom Hughes <tom@compton.nu>
Sat, 11 Sep 2004 14:16:57 +0000 (14:16 +0000)
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

coregrind/core.h
coregrind/vg_main.c
coregrind/vg_scheduler.c
coregrind/vg_signals.c
coregrind/vg_syscalls.c

index deff8721f5e250d35c9b146d6ff00541d3a2d454..2a99c42f50bc7d29c9a7c6e264f055101ff7fceb 100644 (file)
@@ -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);
index 183fa2ea1a15647dde2535e04e88c42b9d07ca2c..a077d58c0d9d0d3e0a01845bc3de0669f6453916 100644 (file)
@@ -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
index b181746138c7f1a58ff8dda40a8dd0d2113e2947..cf4050c7b9340176400cad2a653cc0f1192bf60a 100644 (file)
@@ -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);
index 4f4061b288320d8fbd786b840189877dcb94d2ac..9a8ace72e7c9866d090ba95caa0e38bc3d9c1b6c 100644 (file)
@@ -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
index 2934f40e453aa27af916d38732f7673f86a9501e..14ea259c99b8d432ea7960a4a1a99e90760e59a1 100644 (file)
@@ -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)