From f3e0d143131dc318a173f4f5cc4e4b96de93318d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B6hrmann?= Date: Wed, 23 Aug 2017 09:05:29 +0200 Subject: [PATCH] runtime: avoid infinite loop in growslice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 386 the below code triggered an infinite loop in growslice: x = make([]byte, 1<<30-1, 1<<30-1) x = append(x, x...) Check for overflow when calculating the new slice capacity and set the new capacity to the requested capacity when an overflow is detected to avoid an infinite loop. No automatic test added due to requiring to allocate 1GB of memory on a 32bit plaform before use of append is able to trigger the overflow check. Fixes #21441 Change-Id: Ia871cc9f88479dacf2c7044531b233f83d2fcedf Reviewed-on: https://go-review.googlesource.com/57950 Run-TryBot: Martin Möhrmann TryBot-Result: Gobot Gobot Reviewed-by: Marvin Stenger Reviewed-by: Keith Randall --- src/runtime/slice.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/runtime/slice.go b/src/runtime/slice.go index daaf24e721..84db7ebc3a 100644 --- a/src/runtime/slice.go +++ b/src/runtime/slice.go @@ -105,9 +105,16 @@ func growslice(et *_type, old slice, cap int) slice { if old.len < 1024 { newcap = doublecap } else { - for newcap < cap { + // Check 0 < newcap to detect overflow + // and prevent an infinite loop. + for 0 < newcap && newcap < cap { newcap += newcap / 4 } + // Set newcap to the requested cap when + // the newcap calculation overflowed. + if newcap <= 0 { + newcap = cap + } } }