]> Cypherpunks repositories - gostls13.git/commitdiff
internal/saferio: handle potential total size overflow in SliceCap
authorZeke Lu <lvzecai@gmail.com>
Mon, 26 Sep 2022 14:53:54 +0000 (14:53 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 26 Sep 2022 20:36:02 +0000 (20:36 +0000)
Before the change, "SliceCap((*int64)(nil), 1<<62)" returns 1<<62.
That's because "uintptr(c)*size" overflows and gives 0 which is less
than the "chunk". SliceCap should return -1 in this case.

Change-Id: I4e99224c8ac0fc72032c6be86d7318d33d083cd8
GitHub-Last-Rev: ca30bcce456d20702e3699822cd4f1c963ef1cec
GitHub-Pull-Request: golang/go#55870
Reviewed-on: https://go-review.googlesource.com/c/go/+/434335
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>

src/internal/saferio/io.go
src/internal/saferio/io_test.go

index b10d11751310eafa67ad12fb63308f8712e0c687..66cc044c745d93c16624218fbf0023232bed40ce 100644 (file)
@@ -121,8 +121,11 @@ func SliceCap(v any, c uint64) int {
        if typ.Kind() != reflect.Ptr {
                panic("SliceCap called with non-pointer type")
        }
-       size := typ.Elem().Size()
-       if uintptr(c)*size > chunk {
+       size := uint64(typ.Elem().Size())
+       if size > 0 && c > (1<<64-1)/size {
+               return -1
+       }
+       if c*size > chunk {
                c = uint64(chunk / size)
                if c == 0 {
                        c = 1
index 290181f2a072075fa0f0c31ed767a56b46bfc2df..356c9ebdd1a60880b8b89966b9a701b5a7481244 100644 (file)
@@ -126,4 +126,11 @@ func TestSliceCap(t *testing.T) {
                        t.Errorf("SliceCap returned %d, expected failure", c)
                }
        })
+
+       t.Run("overflow", func(t *testing.T) {
+               c := SliceCap((*int64)(nil), 1<<62)
+               if c >= 0 {
+                       t.Errorf("SliceCap returned %d, expected failure", c)
+               }
+       })
 }