aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa
diff options
context:
space:
mode:
authorJunyang Shao <shaojunyang@google.com>2026-03-06 00:03:45 +0000
committerGopher Robot <gobot@golang.org>2026-04-08 05:23:56 -0700
commitf5b77a7e2fa0f7ff346c665974a8eded367b1bc2 (patch)
tree04871d78b100e410014b20bb4afc22b8a19cdd5b /src/cmd/compile/internal/ssa
parent3985ca0b6264835c049e601900a8072b5d1b13b4 (diff)
downloadgo-f5b77a7e2fa0f7ff346c665974a8eded367b1bc2.tar.xz
cmd/compile: fix loopbce overflow check logic
addWillOverflow and subWillOverflow has an implicit assumption that y is positive, using it outside of addU and subU is really incorrect. This CL fixes those incorrect usage to use the correct logic in place. Thanks to Jakub Ciolek for reporting this issue. Fixes #78333 Fixes CVE-2026-27143 Change-Id: I263e8e7ac227e2a68109eb7bbd45f66569ed22ec Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3700 Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Neal Patel <nealpatel@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/763765 Reviewed-by: Jakub Ciolek <jakub@ciolek.dev> Reviewed-by: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa')
-rw-r--r--src/cmd/compile/internal/ssa/loopbce.go36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go
index fc96834b88..0d3130fe9a 100644
--- a/src/cmd/compile/internal/ssa/loopbce.go
+++ b/src/cmd/compile/internal/ssa/loopbce.go
@@ -235,9 +235,11 @@ nextblock:
if init.AuxInt > v {
return false
}
+ // TODO(1.27): investigate passing a smaller-magnitude overflow limit to addU
+ // for addWillOverflow.
v = addU(init.AuxInt, diff(v, init.AuxInt)/uint64(step)*uint64(step))
}
- if addWillOverflow(v, step) {
+ if addWillOverflow(v, step, maxSignedValue(ind.Type)) {
return false
}
if inclusive && v != limit.AuxInt || !inclusive && v+1 != limit.AuxInt {
@@ -271,7 +273,7 @@ nextblock:
// for i := 0; i < KNN&^(k-1) ; i += k // k a power of 2
// for i := 0; i < KNN&(-k) ; i += k // k a power of 2
} else { // step < 0
- if limit.Op == OpConst64 {
+ if limit.isGenericIntConst() {
// Figure out the actual smallest value.
v := limit.AuxInt
if !inclusive {
@@ -285,9 +287,11 @@ nextblock:
if init.AuxInt < v {
return false
}
+ // TODO(1.27): investigate passing a smaller-magnitude underflow limit to subU
+ // for subWillUnderflow.
v = subU(init.AuxInt, diff(init.AuxInt, v)/uint64(-step)*uint64(-step))
}
- if subWillUnderflow(v, -step) {
+ if subWillUnderflow(v, -step, minSignedValue(ind.Type)) {
return false
}
if inclusive && v != limit.AuxInt || !inclusive && v-1 != limit.AuxInt {
@@ -347,14 +351,22 @@ nextblock:
return iv
}
-// addWillOverflow reports whether x+y would result in a value more than maxint.
-func addWillOverflow(x, y int64) bool {
- return x+y < x
+// subWillUnderflow checks if x - y underflows the min value.
+// y must be positive.
+func subWillUnderflow(x, y int64, min int64) bool {
+ if y < 0 {
+ base.Fatalf("expecting positive value")
+ }
+ return x < min+y
}
-// subWillUnderflow reports whether x-y would result in a value less than minint.
-func subWillUnderflow(x, y int64) bool {
- return x-y > x
+// addWillOverflow checks if x + y overflows the max value.
+// y must be positive.
+func addWillOverflow(x, y int64, max int64) bool {
+ if y < 0 {
+ base.Fatalf("expecting positive value")
+ }
+ return x > max-y
}
// diff returns x-y as a uint64. Requires x>=y.
@@ -375,7 +387,8 @@ func addU(x int64, y uint64) int64 {
x += 1
y -= 1 << 63
}
- if addWillOverflow(x, int64(y)) {
+ // TODO(1.27): investigate passing a smaller-magnitude overflow limit in here.
+ if addWillOverflow(x, int64(y), maxSignedValue(types.Types[types.TINT64])) {
base.Fatalf("addU overflowed %d + %d", x, y)
}
return x + int64(y)
@@ -391,7 +404,8 @@ func subU(x int64, y uint64) int64 {
x -= 1
y -= 1 << 63
}
- if subWillUnderflow(x, int64(y)) {
+ // TODO(1.27): investigate passing a smaller-magnitude underflow limit in here.
+ if subWillUnderflow(x, int64(y), minSignedValue(types.Types[types.TINT64])) {
base.Fatalf("subU underflowed %d - %d", x, y)
}
return x - int64(y)