Commit f322c786 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov Committed by Ian Lance Taylor

runtime: fix crash in badsignal()

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
parent b3b1efd8
...@@ -540,14 +540,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go: ...@@ -540,14 +540,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
void void
runtime·badsignal(int32 sig) runtime·badsignal(int32 sig)
{ {
int32 len;
if (sig == SIGPROF) { if (sig == SIGPROF) {
return; // Ignore SIGPROFs intended for a non-Go thread. return; // Ignore SIGPROFs intended for a non-Go thread.
} }
runtime·write(2, badsignal, sizeof badsignal - 1); runtime·write(2, badsignal, sizeof badsignal - 1);
if (0 <= sig && sig < NSIG) { if (0 <= sig && sig < NSIG) {
// Call runtime·findnull dynamically to circumvent static stack size check. // Can't call findnull() because it will split stack.
static int32 (*findnull)(byte*) = runtime·findnull; for(len = 0; runtime·sigtab[sig].name[len]; len++)
runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name)); ;
runtime·write(2, runtime·sigtab[sig].name, len);
} }
runtime·write(2, "\n", 1); runtime·write(2, "\n", 1);
runtime·exit(1); runtime·exit(1);
......
...@@ -252,14 +252,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go: ...@@ -252,14 +252,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
void void
runtime·badsignal(int32 sig) runtime·badsignal(int32 sig)
{ {
int32 len;
if (sig == SIGPROF) { if (sig == SIGPROF) {
return; // Ignore SIGPROFs intended for a non-Go thread. return; // Ignore SIGPROFs intended for a non-Go thread.
} }
runtime·write(2, badsignal, sizeof badsignal - 1); runtime·write(2, badsignal, sizeof badsignal - 1);
if (0 <= sig && sig < NSIG) { if (0 <= sig && sig < NSIG) {
// Call runtime·findnull dynamically to circumvent static stack size check. // Can't call findnull() because it will split stack.
static int32 (*findnull)(byte*) = runtime·findnull; for(len = 0; runtime·sigtab[sig].name[len]; len++)
runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name)); ;
runtime·write(2, runtime·sigtab[sig].name, len);
} }
runtime·write(2, "\n", 1); runtime·write(2, "\n", 1);
runtime·exit(1); runtime·exit(1);
......
...@@ -300,14 +300,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go: ...@@ -300,14 +300,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
void void
runtime·badsignal(int32 sig) runtime·badsignal(int32 sig)
{ {
int32 len;
if (sig == SIGPROF) { if (sig == SIGPROF) {
return; // Ignore SIGPROFs intended for a non-Go thread. return; // Ignore SIGPROFs intended for a non-Go thread.
} }
runtime·write(2, badsignal, sizeof badsignal - 1); runtime·write(2, badsignal, sizeof badsignal - 1);
if (0 <= sig && sig < NSIG) { if (0 <= sig && sig < NSIG) {
// Call runtime·findnull dynamically to circumvent static stack size check. // Can't call findnull() because it will split stack.
static int32 (*findnull)(byte*) = runtime·findnull; for(len = 0; runtime·sigtab[sig].name[len]; len++)
runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name)); ;
runtime·write(2, runtime·sigtab[sig].name, len);
} }
runtime·write(2, "\n", 1); runtime·write(2, "\n", 1);
runtime·exit(1); runtime·exit(1);
......
...@@ -292,14 +292,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go: ...@@ -292,14 +292,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
void void
runtime·badsignal(int32 sig) runtime·badsignal(int32 sig)
{ {
int32 len;
if (sig == SIGPROF) { if (sig == SIGPROF) {
return; // Ignore SIGPROFs intended for a non-Go thread. return; // Ignore SIGPROFs intended for a non-Go thread.
} }
runtime·write(2, badsignal, sizeof badsignal - 1); runtime·write(2, badsignal, sizeof badsignal - 1);
if (0 <= sig && sig < NSIG) { if (0 <= sig && sig < NSIG) {
// Call runtime·findnull dynamically to circumvent static stack size check. // Can't call findnull() because it will split stack.
static int32 (*findnull)(byte*) = runtime·findnull; for(len = 0; runtime·sigtab[sig].name[len]; len++)
runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name)); ;
runtime·write(2, runtime·sigtab[sig].name, len);
} }
runtime·write(2, "\n", 1); runtime·write(2, "\n", 1);
runtime·exit(1); runtime·exit(1);
......
...@@ -274,14 +274,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go: ...@@ -274,14 +274,17 @@ static int8 badsignal[] = "runtime: signal received on thread not created by Go:
void void
runtime·badsignal(int32 sig) runtime·badsignal(int32 sig)
{ {
int32 len;
if (sig == SIGPROF) { if (sig == SIGPROF) {
return; // Ignore SIGPROFs intended for a non-Go thread. return; // Ignore SIGPROFs intended for a non-Go thread.
} }
runtime·write(2, badsignal, sizeof badsignal - 1); runtime·write(2, badsignal, sizeof badsignal - 1);
if (0 <= sig && sig < NSIG) { if (0 <= sig && sig < NSIG) {
// Call runtime·findnull dynamically to circumvent static stack size check. // Can't call findnull() because it will split stack.
static int32 (*findnull)(byte*) = runtime·findnull; for(len = 0; runtime·sigtab[sig].name[len]; len++)
runtime·write(2, runtime·sigtab[sig].name, findnull((byte*)runtime·sigtab[sig].name)); ;
runtime·write(2, runtime·sigtab[sig].name, len);
} }
runtime·write(2, "\n", 1); runtime·write(2, "\n", 1);
runtime·exit(1); runtime·exit(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment