]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: detect stack split after fork
authorDmitriy Vyukov <dvyukov@google.com>
Thu, 13 Mar 2014 13:41:08 +0000 (17:41 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Thu, 13 Mar 2014 13:41:08 +0000 (17:41 +0400)
This check would allowed to easily prevent issue 7511.
Update #7511

LGTM=rsc
R=rsc, aram
CC=golang-codereviews
https://golang.org/cl/75260043

src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h
src/pkg/runtime/stack.c

index d3ad7401364e751b7e703d8f46ed6a0cb6c58a44..e11f9b18ac8c6cfd6a471f1be40ba868587a080f 100644 (file)
@@ -1704,14 +1704,28 @@ syscall·runtime_BeforeFork(void)
        m->locks++;
        if(m->profilehz != 0)
                runtime·resetcpuprofiler(0);
+
+       // This function is called before fork in syscall package.
+       // Code between fork and exec must not allocate memory nor even try to grow stack.
+       // Here we spoil g->stackguard to reliably detect any attempts to grow stack.
+       // runtime_AfterFork will undo this in parent process, but not in child.
+       m->forkstackguard = g->stackguard;
+       g->stackguard0 = StackPreempt-1;
+       g->stackguard = StackPreempt-1;
 }
 
 // Called from syscall package after fork in parent.
+#pragma textflag NOSPLIT
 void
 syscall·runtime_AfterFork(void)
 {
        int32 hz;
 
+       // See the comment in runtime_BeforeFork.
+       g->stackguard0 = m->forkstackguard;
+       g->stackguard = m->forkstackguard;
+       m->forkstackguard = 0;
+
        hz = runtime·sched.profilehz;
        if(hz != 0)
                runtime·resetcpuprofiler(hz);
index ecff533f59b2ee041c88821f61118085ca3c213b..8e5e9a12944658d9e493cf0267bf79380d4fc7e5 100644 (file)
@@ -367,6 +367,7 @@ struct      M
        bool    needextram;
        bool    (*waitunlockf)(G*, void*);
        void*   waitlock;
+       uintptr forkstackguard;
 #ifdef GOOS_windows
        void*   thread;         // thread handle
        // these are here because they are too large to be on the stack
index bb7a32f8ae7a1dbe54fb84e6872325de8cfdc0d7..d580665e2bd3d61024b271cd5a6e3fa3b8474e9e 100644 (file)
@@ -583,6 +583,8 @@ runtime·newstack(void)
        Gobuf label;
        bool newstackcall;
 
+       if(m->forkstackguard)
+               runtime·throw("split stack after fork");
        if(m->morebuf.g != m->curg) {
                runtime·printf("runtime: newstack called from g=%p\n"
                        "\tm=%p m->curg=%p m->g0=%p m->gsignal=%p\n",