]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix crash in badsignal()
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 6 May 2013 23:15:03 +0000 (16:15 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 6 May 2013 23:15:03 +0000 (16:15 -0700)
The linker can generate split stack prolog when a textflag 7 function
makes an indirect function call.  If it happens, badsignal() crashes
trying to dereference g.
Fixes #5337.

R=bradfitz, dave, adg, iant, r, minux.ma
CC=adonovan, golang-dev
https://golang.org/cl/9226043

src/pkg/runtime/os_darwin.c
src/pkg/runtime/os_freebsd.c
src/pkg/runtime/os_linux.c
src/pkg/runtime/os_netbsd.c
src/pkg/runtime/os_openbsd.c

index 390e76ec58f68b55fd37f5f89d26c8d10ed7b129..276362a97f6d094e51cb23e8f72974d4b310d8a5 100644 (file)
@@ -540,14 +540,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
 void
 runtime·badsignal(int32 sig)
 {
+       int32 len;
+
        if (sig == SIGPROF) {
                return;  // Ignore SIGPROFs intended for a non-Go thread.
        }
        runtime·write(2, badsignal, sizeof badsignal - 1);
        if (0 <= sig && sig < NSIG) {
-               // Call runtime·findnull dynamically to circumvent static stack size check.
-               static int32 (*findnull)(byte*) = runtime·findnull;
-               runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name));
+               // Can't call findnull() because it will split stack.
+               for(len = 0; runtime·sigtab[sig].name[len]; len++)
+                       ;
+               runtime·write(2, runtime·sigtab[sig].name, len);
        }
        runtime·write(2, "\n", 1);
        runtime·exit(1);
index 357ad80dc1a295ff10c4a6969f49ee8b60e55642..f454ab3497725ddef5f946eb79fb13d973a3df92 100644 (file)
@@ -252,14 +252,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
 void
 runtime·badsignal(int32 sig)
 {
+       int32 len;
+
        if (sig == SIGPROF) {
                return;  // Ignore SIGPROFs intended for a non-Go thread.
        }
        runtime·write(2, badsignal, sizeof badsignal - 1);
        if (0 <= sig && sig < NSIG) {
-               // Call runtime·findnull dynamically to circumvent static stack size check.
-               static int32 (*findnull)(byte*) = runtime·findnull;
-               runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name));
+               // Can't call findnull() because it will split stack.
+               for(len = 0; runtime·sigtab[sig].name[len]; len++)
+                       ;
+               runtime·write(2, runtime·sigtab[sig].name, len);
        }
        runtime·write(2, "\n", 1);
        runtime·exit(1);
index e4ae1a5d80005ea3105c16afe83c3547ccdedf8f..6b86d2b1777a29f8efb4a031c17b141eb1eeadd5 100644 (file)
@@ -300,14 +300,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
 void
 runtime·badsignal(int32 sig)
 {
+       int32 len;
+
        if (sig == SIGPROF) {
                return;  // Ignore SIGPROFs intended for a non-Go thread.
        }
        runtime·write(2, badsignal, sizeof badsignal - 1);
        if (0 <= sig && sig < NSIG) {
-               // Call runtime·findnull dynamically to circumvent static stack size check.
-               static int32 (*findnull)(byte*) = runtime·findnull;
-               runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name));
+               // Can't call findnull() because it will split stack.
+               for(len = 0; runtime·sigtab[sig].name[len]; len++)
+                       ;
+               runtime·write(2, runtime·sigtab[sig].name, len);
        }
        runtime·write(2, "\n", 1);
        runtime·exit(1);
index 936334cac6f3f261e71f82f0499bd1398c258d0e..7679ec2552e20d66cb07e05269c473c68c7fe239 100644 (file)
@@ -292,14 +292,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
 void
 runtime·badsignal(int32 sig)
 {
+       int32 len;
+
        if (sig == SIGPROF) {
                return;  // Ignore SIGPROFs intended for a non-Go thread.
        }
        runtime·write(2, badsignal, sizeof badsignal - 1);
        if (0 <= sig && sig < NSIG) {
-               // Call runtime·findnull dynamically to circumvent static stack size check.
-               static int32 (*findnull)(byte*) = runtime·findnull;
-               runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name));
+               // Can't call findnull() because it will split stack.
+               for(len = 0; runtime·sigtab[sig].name[len]; len++)
+                       ;
+               runtime·write(2, runtime·sigtab[sig].name, len);
        }
        runtime·write(2, "\n", 1);
        runtime·exit(1);
index 4ce64f9f2a49c558d16bbec06927920c3bfb8ee9..4ce102ec2cb64df6f0419981949e11e36e116514 100644 (file)
@@ -274,14 +274,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
 void
 runtime·badsignal(int32 sig)
 {
+       int32 len;
+
        if (sig == SIGPROF) {
                return;  // Ignore SIGPROFs intended for a non-Go thread.
        }
        runtime·write(2, badsignal, sizeof badsignal - 1);
        if (0 <= sig && sig < NSIG) {
-               // Call runtime·findnull dynamically to circumvent static stack size check.
-               static int32 (*findnull)(byte*) = runtime·findnull;
-               runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name));
+               // Can't call findnull() because it will split stack.
+               for(len = 0; runtime·sigtab[sig].name[len]; len++)
+                       ;
+               runtime·write(2, runtime·sigtab[sig].name, len);
        }
        runtime·write(2, "\n", 1);
        runtime·exit(1);