runtime: on android/arm64, don't read outside 16-byte regions

Because MTE might be enforced.

Update #59090
Update #27610

Change-Id: Idfaecbf3b7a93c5e371abcace666febfc303de9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/749062
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Keith Randall
2026-02-25 07:32:42 -08:00
committed by Gopher Robot
parent 5055a18156
commit f5479628d3
2 changed files with 25 additions and 1 deletions

View File

@@ -34,6 +34,9 @@ TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32
// identify exactly which byte has matched.
CBZ R1, fail
#ifdef GOOS_android
ADD R0, R1, R20 // R20 = end of data
#endif
MOVD R0, R11
// Magic constant 0x40100401 allows us to identify
// which lane matches the requested byte.
@@ -51,7 +54,17 @@ TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32
// Input string is not 32-byte aligned. We calculate the
// syndrome value for the aligned 32 bytes block containing
// the first bytes and mask off the irrelevant part.
#ifdef GOOS_android
// Android requires us to not read outside an aligned 16-byte
// region because MTE might be enforced.
VLD1.P (R3), [V1.B16]
CMP R3, R20
BLS 2(PC)
VLD1 (R3), [V2.B16]
ADD $0x10, R3
#else
VLD1.P (R3), [V1.B16, V2.B16]
#endif
SUB $0x20, R9, R4
ADDS R4, R1, R1
VCMEQ V0.B16, V1.B16, V3.B16
@@ -71,7 +84,15 @@ TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32
CBNZ R6, tail
loop:
#ifdef GOOS_android
VLD1.P (R3), [V1.B16]
CMP R3, R20
BLS 2(PC)
VLD1 (R3), [V2.B16]
ADD $0x10, R3
#else
VLD1.P (R3), [V1.B16, V2.B16]
#endif
SUBS $0x20, R1, R1
VCMEQ V0.B16, V1.B16, V3.B16
VCMEQ V0.B16, V2.B16, V4.B16

View File

@@ -8,6 +8,7 @@ import (
"internal/abi"
"internal/bytealg"
"internal/goarch"
"internal/goos"
"internal/runtime/math"
"internal/runtime/sys"
"internal/strconv"
@@ -505,7 +506,9 @@ func findnull(s *byte) int {
// It must be the minimum page size for any architecture Go
// runs on. It's okay (just a minor performance loss) if the
// actual system page size is larger than this value.
const pageSize = 4096
// For Android, we set the page size to the MTE size, as MTE
// might be enforced. See issue 59090.
const pageSize = 4096*(1-goos.IsAndroid) + 16*goos.IsAndroid
offset := 0
ptr := unsafe.Pointer(s)