diff options
| author | Alberto Donizetti <alb.donizetti@gmail.com> | 2016-10-20 11:24:51 +0200 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2016-10-20 21:08:18 +0000 |
| commit | 10560afb540b783da568aebe83d0f782e46bb673 (patch) | |
| tree | 589e68bbc19fed944d1205ca1af7b1c224f2537a /src/runtime | |
| parent | f6f3aef53f7ef6085ea14b6147b2478848778709 (diff) | |
| download | go-10560afb540b783da568aebe83d0f782e46bb673.tar.xz | |
runtime/debug: avoid overflow in SetMaxThreads
Fixes #16076
Change-Id: I91fa87b642592ee4604537dd8c3197cd61ec8b31
Reviewed-on: https://go-review.googlesource.com/31516
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/debug/garbage_test.go | 13 | ||||
| -rw-r--r-- | src/runtime/proc.go | 6 |
2 files changed, 18 insertions, 1 deletions
diff --git a/src/runtime/debug/garbage_test.go b/src/runtime/debug/garbage_test.go index d1fa7db23a..6b03455cf9 100644 --- a/src/runtime/debug/garbage_test.go +++ b/src/runtime/debug/garbage_test.go @@ -114,3 +114,16 @@ func TestSetGCPercent(t *testing.T) { t.Errorf("SetGCPercent(123); SetGCPercent(x) = %d, want 123", new) } } + +func TestSetMaxThreadsOvf(t *testing.T) { + // Verify that a big threads count will not overflow the int32 + // maxmcount variable, causing a panic (see Issue 16076). + // + // This can only happen when ints are 64 bits, since on platforms + // with 32 bit ints SetMaxThreads (which takes an int parameter) + // cannot be given anything that will overflow an int32. + // + // Call SetMaxThreads with 1<<31, but only on 64 bit systems. + nt := SetMaxThreads(1 << (30 + ^uint(0)>>63)) + SetMaxThreads(nt) // restore previous value +} diff --git a/src/runtime/proc.go b/src/runtime/proc.go index f68a189997..9fc24e3ae3 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -4294,7 +4294,11 @@ func runqsteal(_p_, p2 *p, stealRunNextG bool) *g { func setMaxThreads(in int) (out int) { lock(&sched.lock) out = int(sched.maxmcount) - sched.maxmcount = int32(in) + if in > 0x7fffffff { // MaxInt32 + sched.maxmcount = 0x7fffffff + } else { + sched.maxmcount = int32(in) + } checkmcount() unlock(&sched.lock) return |
