aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorhiddenpath <hiddenpath@yandex-team.com>2024-01-26 19:49:19 +0300
committerhiddenpath <hiddenpath@yandex-team.com>2024-01-26 20:08:56 +0300
commitf6d7ec162ce757a854f4a619d6b0c7084ad48f3e (patch)
treed3176e091caaa7b6cdebda4944ac265de533a6da /contrib
parent27b1811df443f5a3d16e2ae0f1744f39b348109d (diff)
downloadydb-f6d7ec162ce757a854f4a619d6b0c7084ad48f3e.tar.gz
Update golang to 1.21.6
Diffstat (limited to 'contrib')
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go1
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand.go2
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_windows.go7
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go8
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client.go4
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go4
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go7
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/notboring.go2
-rw-r--r--contrib/go/_std_1.21/src/go/types/call.go8
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go2
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/splice_linux.go21
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go98
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go1
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go2
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go21
-rw-r--r--contrib/go/_std_1.21/src/net/http/h2_bundle.go1
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/chunked.go34
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit.go32
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_darwin.go22
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_stub.go12
-rw-r--r--contrib/go/_std_1.21/src/os/types_windows.go18
-rw-r--r--contrib/go/_std_1.21/src/os/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path.go17
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go9
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_windows.go188
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/ya.make6
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s7
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s7
-rw-r--r--contrib/go/_std_1.21/src/runtime/extern.go7
-rw-r--r--contrib/go/_std_1.21/src/runtime/malloc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/map.go22
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem_linux.go8
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcscavenge.go20
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpagealloc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/mstats.go114
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_windows.go33
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/proto.go7
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime.go13
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime1.go2
40 files changed, 462 insertions, 329 deletions
diff --git a/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
index 1c5e4c742d..e478791217 100644
--- a/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
@@ -50,6 +50,7 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: no
func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") }
func NewGCMTLS(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }
+func NewGCMTLS13(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }
type PublicKeyECDSA struct{ _ int }
type PrivateKeyECDSA struct{ _ int }
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand.go b/contrib/go/_std_1.21/src/crypto/rand/rand.go
index 62738e2cb1..d0dcc7cc71 100644
--- a/contrib/go/_std_1.21/src/crypto/rand/rand.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand.go
@@ -15,7 +15,7 @@ import "io"
// available, /dev/urandom otherwise.
// On OpenBSD and macOS, Reader uses getentropy(2).
// On other Unix-like systems, Reader reads from /dev/urandom.
-// On Windows systems, Reader uses the RtlGenRandom API.
+// On Windows systems, Reader uses the ProcessPrng API.
// On JS/Wasm, Reader uses the Web Crypto API.
// On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1.
var Reader io.Reader
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
index 6c0655c72b..7380f1f0f1 100644
--- a/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
@@ -15,11 +15,8 @@ func init() { Reader = &rngReader{} }
type rngReader struct{}
-func (r *rngReader) Read(b []byte) (n int, err error) {
- // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at
- // most 1<<31-1 bytes at a time so that this works the same on 32-bit
- // and 64-bit systems.
- if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil {
+func (r *rngReader) Read(b []byte) (int, error) {
+ if err := windows.ProcessPrng(b); err != nil {
return 0, err
}
return len(b), nil
diff --git a/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
index 589e8b6faf..fd538da0f7 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
@@ -532,7 +532,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
if err != nil {
panic(err)
}
- aead, err := cipher.NewGCM(aes)
+ var aead cipher.AEAD
+ if boring.Enabled {
+ aead, err = boring.NewGCMTLS13(aes)
+ } else {
+ boring.Unreachable()
+ aead, err = cipher.NewGCM(aes)
+ }
if err != nil {
panic(err)
}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
index 4649f36dea..e81764a912 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
@@ -139,7 +139,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
if len(hello.supportedVersions) == 1 {
hello.cipherSuites = nil
}
- if hasAESGCMHardwareSupport {
+ if needFIPS() {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13FIPS...)
+ } else if hasAESGCMHardwareSupport {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
} else {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
index 2f59f6888c..a84cede1b0 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
@@ -41,10 +41,6 @@ type clientHandshakeStateTLS13 struct {
func (hs *clientHandshakeStateTLS13) handshake() error {
c := hs.c
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
// sections 4.1.2 and 4.1.3.
if c.handshakes > 0 {
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
index 07b1a3851e..dd5298b728 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
@@ -45,10 +45,6 @@ type serverHandshakeStateTLS13 struct {
func (hs *serverHandshakeStateTLS13) handshake() error {
c := hs.c
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
if err := hs.processClientHello(); err != nil {
return err
@@ -163,6 +159,9 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
preferenceList = defaultCipherSuitesTLS13NoAES
}
+ if needFIPS() {
+ preferenceList = defaultCipherSuitesTLS13FIPS
+ }
for _, suiteID := range preferenceList {
hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
if hs.suite != nil {
diff --git a/contrib/go/_std_1.21/src/crypto/tls/notboring.go b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
index 7d85b39c59..edccb44d87 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
@@ -18,3 +18,5 @@ func fipsCurvePreferences(c *Config) []CurveID { panic("fipsCurvePreferences") }
func fipsCipherSuites(c *Config) []uint16 { panic("fipsCipherSuites") }
var fipsSupportedSignatureAlgorithms []SignatureScheme
+
+var defaultCipherSuitesTLS13FIPS []uint16
diff --git a/contrib/go/_std_1.21/src/go/types/call.go b/contrib/go/_std_1.21/src/go/types/call.go
index 8a3cec7309..f00290a74f 100644
--- a/contrib/go/_std_1.21/src/go/types/call.go
+++ b/contrib/go/_std_1.21/src/go/types/call.go
@@ -571,6 +571,14 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
+ // The argument type is a generic function signature. This type is
+ // pointer-identical with (it's copied from) the type of the generic
+ // function argument and thus the function object.
+ // Before we change the type (type parameter renaming, below), make
+ // a clone of it as otherwise we implicitly modify the object's type
+ // (go.dev/issues/63260).
+ clone := *asig
+ asig = &clone
// Rename type parameters for cases like f(g, g); this gives each
// generic function argument a unique type identity (go.dev/issues/59956).
// TODO(gri) Consider only doing this if a function argument appears
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
index f5b4f3486b..b83b3ead43 100644
--- a/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
@@ -13,6 +13,6 @@ const defaultGOPPC64 = `power8`
const defaultGOEXPERIMENT = ``
const defaultGO_EXTLINK_ENABLED = ``
const defaultGO_LDSO = ``
-const version = `go1.21.3`
+const version = `go1.21.6`
const defaultGOOS = runtime.GOOS
const defaultGOARCH = runtime.GOARCH
diff --git a/contrib/go/_std_1.21/src/internal/poll/splice_linux.go b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
index 9505c5dcfc..72cca34fe4 100644
--- a/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
+++ b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
@@ -13,6 +13,12 @@ import (
)
const (
+ // spliceNonblock doesn't make the splice itself necessarily nonblocking
+ // (because the actual file descriptors that are spliced from/to may block
+ // unless they have the O_NONBLOCK flag set), but it makes the splice pipe
+ // operations nonblocking.
+ spliceNonblock = 0x2
+
// maxSpliceSize is the maximum amount of data Splice asks
// the kernel to move in a single call to splice(2).
// We use 1MB as Splice writes data through a pipe, and 1MB is the default maximum pipe buffer size,
@@ -89,7 +95,11 @@ func spliceDrain(pipefd int, sock *FD, max int) (int, error) {
return 0, err
}
for {
- n, err := splice(pipefd, sock.Sysfd, max, 0)
+ // In theory calling splice(2) with SPLICE_F_NONBLOCK could end up an infinite loop here,
+ // because it could return EAGAIN ceaselessly when the write end of the pipe is full,
+ // but this shouldn't be a concern here, since the pipe buffer must be sufficient for
+ // this data transmission on the basis of the workflow in Splice.
+ n, err := splice(pipefd, sock.Sysfd, max, spliceNonblock)
if err == syscall.EINTR {
continue
}
@@ -127,7 +137,14 @@ func splicePump(sock *FD, pipefd int, inPipe int) (int, error) {
}
written := 0
for inPipe > 0 {
- n, err := splice(sock.Sysfd, pipefd, inPipe, 0)
+ // In theory calling splice(2) with SPLICE_F_NONBLOCK could end up an infinite loop here,
+ // because it could return EAGAIN ceaselessly when the read end of the pipe is empty,
+ // but this shouldn't be a concern here, since the pipe buffer must contain inPipe size of
+ // data on the basis of the workflow in Splice.
+ n, err := splice(sock.Sysfd, pipefd, inPipe, spliceNonblock)
+ if err == syscall.EINTR {
+ continue
+ }
// Here, the condition n == 0 && err == nil should never be
// observed, since Splice controls the write side of the pipe.
if n > 0 {
diff --git a/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
index 909c150edc..7cfd6ce2ea 100644
--- a/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
@@ -20,15 +20,10 @@ func fromFS(path string) (string, error) {
for p := path; p != ""; {
// Find the next path element.
i := 0
- dot := -1
for i < len(p) && p[i] != '/' {
switch p[i] {
case 0, '\\', ':':
return "", errInvalidPath
- case '.':
- if dot < 0 {
- dot = i
- }
}
i++
}
@@ -39,22 +34,8 @@ func fromFS(path string) (string, error) {
} else {
p = ""
}
- // Trim the extension and look for a reserved name.
- base := part
- if dot >= 0 {
- base = part[:dot]
- }
- if isReservedName(base) {
- if dot < 0 {
- return "", errInvalidPath
- }
- // The path element is a reserved name with an extension.
- // Some Windows versions consider this a reserved name,
- // while others do not. Use FullPath to see if the name is
- // reserved.
- if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
- return "", errInvalidPath
- }
+ if IsReservedName(part) {
+ return "", errInvalidPath
}
}
if containsSlash {
@@ -70,23 +51,88 @@ func fromFS(path string) (string, error) {
return path, nil
}
-// isReservedName reports if name is a Windows reserved device name.
+// IsReservedName reports if name is a Windows reserved device name.
// It does not detect names with an extension, which are also reserved on some Windows versions.
//
// For details, search for PRN in
// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
-func isReservedName(name string) bool {
- if 3 <= len(name) && len(name) <= 4 {
+func IsReservedName(name string) bool {
+ // Device names can have arbitrary trailing characters following a dot or colon.
+ base := name
+ for i := 0; i < len(base); i++ {
+ switch base[i] {
+ case ':', '.':
+ base = base[:i]
+ }
+ }
+ // Trailing spaces in the last path element are ignored.
+ for len(base) > 0 && base[len(base)-1] == ' ' {
+ base = base[:len(base)-1]
+ }
+ if !isReservedBaseName(base) {
+ return false
+ }
+ if len(base) == len(name) {
+ return true
+ }
+ // The path element is a reserved name with an extension.
+ // Some Windows versions consider this a reserved name,
+ // while others do not. Use FullPath to see if the name is
+ // reserved.
+ if p, _ := syscall.FullPath(name); len(p) >= 4 && p[:4] == `\\.\` {
+ return true
+ }
+ return false
+}
+
+func isReservedBaseName(name string) bool {
+ if len(name) == 3 {
switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "CON", "PRN", "AUX", "NUL":
- return len(name) == 3
+ return true
+ }
+ }
+ if len(name) >= 4 {
+ switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "COM", "LPT":
- return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
+ if len(name) == 4 && '1' <= name[3] && name[3] <= '9' {
+ return true
+ }
+ // Superscript ¹, ², and ³ are considered numbers as well.
+ switch name[3:] {
+ case "\u00b2", "\u00b3", "\u00b9":
+ return true
+ }
+ return false
}
}
+
+ // Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
+ //
+ // While CONIN$ and CONOUT$ aren't documented as being files,
+ // they behave the same as CON. For example, ./CONIN$ also opens the console input.
+ if len(name) == 6 && name[5] == '$' && equalFold(name, "CONIN$") {
+ return true
+ }
+ if len(name) == 7 && name[6] == '$' && equalFold(name, "CONOUT$") {
+ return true
+ }
return false
}
+func equalFold(a, b string) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := 0; i < len(a); i++ {
+ if toUpper(a[i]) != toUpper(b[i]) {
+ return false
+ }
+ }
+ return true
+}
+
func toUpper(c byte) byte {
if 'a' <= c && c <= 'z' {
return c - ('a' - 'A')
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
index 6e111392f0..6caf47e867 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
@@ -12,6 +12,7 @@ import (
const (
FSCTL_SET_REPARSE_POINT = 0x000900A4
IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
+ IO_REPARSE_TAG_DEDUP = 0x80000013
SYMLINK_FLAG_RELATIVE = 1
)
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
index 892b878d16..e9390b07cd 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
@@ -373,7 +373,7 @@ func ErrorLoadingGetTempPath2() error {
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
-//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
+//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng
//sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry
//sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
index a5c246b773..26ec290e02 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
@@ -37,13 +37,14 @@ func errnoErr(e syscall.Errno) error {
}
var (
- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
+ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
+ modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll"))
+ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
+ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
+ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
+ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
+ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
+ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
@@ -52,7 +53,7 @@ var (
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
- procSystemFunction036 = modadvapi32.NewProc("SystemFunction036")
+ procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng")
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
procCreateEventW = modkernel32.NewProc("CreateEventW")
procGetACP = modkernel32.NewProc("GetACP")
@@ -148,12 +149,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
return
}
-func RtlGenRandom(buf []byte) (err error) {
+func ProcessPrng(buf []byte) (err error) {
var _p0 *byte
if len(buf) > 0 {
_p0 = &buf[0]
}
- r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
+ r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
diff --git a/contrib/go/_std_1.21/src/net/http/h2_bundle.go b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
index 9cd6a3490f..dd59e1f4f2 100644
--- a/contrib/go/_std_1.21/src/net/http/h2_bundle.go
+++ b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
@@ -7012,6 +7012,7 @@ func (sc *http2serverConn) startPush(msg *http2startPushRequest) {
panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
}
+ sc.curHandlers++
go sc.runHandler(rw, req, sc.handler.ServeHTTP)
return promisedID, nil
}
diff --git a/contrib/go/_std_1.21/src/net/http/internal/chunked.go b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
index 5a174415dc..aad8e5aa09 100644
--- a/contrib/go/_std_1.21/src/net/http/internal/chunked.go
+++ b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
@@ -39,7 +39,8 @@ type chunkedReader struct {
n uint64 // unread bytes in chunk
err error
buf [2]byte
- checkEnd bool // whether need to check for \r\n chunk footer
+ checkEnd bool // whether need to check for \r\n chunk footer
+ excess int64 // "excessive" chunk overhead, for malicious sender detection
}
func (cr *chunkedReader) beginChunk() {
@@ -49,10 +50,36 @@ func (cr *chunkedReader) beginChunk() {
if cr.err != nil {
return
}
+ cr.excess += int64(len(line)) + 2 // header, plus \r\n after the chunk data
+ line = trimTrailingWhitespace(line)
+ line, cr.err = removeChunkExtension(line)
+ if cr.err != nil {
+ return
+ }
cr.n, cr.err = parseHexUint(line)
if cr.err != nil {
return
}
+ // A sender who sends one byte per chunk will send 5 bytes of overhead
+ // for every byte of data. ("1\r\nX\r\n" to send "X".)
+ // We want to allow this, since streaming a byte at a time can be legitimate.
+ //
+ // A sender can use chunk extensions to add arbitrary amounts of additional
+ // data per byte read. ("1;very long extension\r\nX\r\n" to send "X".)
+ // We don't want to disallow extensions (although we discard them),
+ // but we also don't want to allow a sender to reduce the signal/noise ratio
+ // arbitrarily.
+ //
+ // We track the amount of excess overhead read,
+ // and produce an error if it grows too large.
+ //
+ // Currently, we say that we're willing to accept 16 bytes of overhead per chunk,
+ // plus twice the amount of real data in the chunk.
+ cr.excess -= 16 + (2 * int64(cr.n))
+ cr.excess = max(cr.excess, 0)
+ if cr.excess > 16*1024 {
+ cr.err = errors.New("chunked encoding contains too much non-data")
+ }
if cr.n == 0 {
cr.err = io.EOF
}
@@ -140,11 +167,6 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) {
if len(p) >= maxLineLength {
return nil, ErrLineTooLong
}
- p = trimTrailingWhitespace(p)
- p, err = removeChunkExtension(p)
- if err != nil {
- return nil, err
- }
return p, nil
}
diff --git a/contrib/go/_std_1.21/src/os/rlimit.go b/contrib/go/_std_1.21/src/os/rlimit.go
deleted file mode 100644
index e0d0ef9b62..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build unix
-
-package os
-
-import "syscall"
-
-// Some systems set an artificially low soft limit on open file count, for compatibility
-// with code that uses select and its hard-coded maximum file descriptor
-// (limited by the size of fd_set).
-//
-// Go does not use select, so it should not be subject to these limits.
-// On some systems the limit is 256, which is very easy to run into,
-// even in simple programs like gofmt when they parallelize walking
-// a file tree.
-//
-// After a long discussion on go.dev/issue/46279, we decided the
-// best approach was for Go to raise the limit unconditionally for itself,
-// and then leave old software to set the limit back as needed.
-// Code that really wants Go to leave the limit alone can set the hard limit,
-// which Go of course has no choice but to respect.
-func init() {
- var lim syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err == nil && lim.Cur != lim.Max {
- lim.Cur = lim.Max
- adjustFileLimit(&lim)
- syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim)
- }
-}
diff --git a/contrib/go/_std_1.21/src/os/rlimit_darwin.go b/contrib/go/_std_1.21/src/os/rlimit_darwin.go
deleted file mode 100644
index b28982a83a..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit_darwin.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin
-
-package os
-
-import "syscall"
-
-// adjustFileLimit adds per-OS limitations on the Rlimit used for RLIMIT_NOFILE. See rlimit.go.
-func adjustFileLimit(lim *syscall.Rlimit) {
- // On older macOS, setrlimit(RLIMIT_NOFILE, lim) with lim.Cur = infinity fails.
- // Set to the value of kern.maxfilesperproc instead.
- n, err := syscall.SysctlUint32("kern.maxfilesperproc")
- if err != nil {
- return
- }
- if lim.Cur > uint64(n) {
- lim.Cur = uint64(n)
- }
-}
diff --git a/contrib/go/_std_1.21/src/os/rlimit_stub.go b/contrib/go/_std_1.21/src/os/rlimit_stub.go
deleted file mode 100644
index cbe28400c5..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit_stub.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-
-package os
-
-import "syscall"
-
-// adjustFileLimit adds per-OS limitations on the Rlimit used for RLIMIT_NOFILE. See rlimit.go.
-func adjustFileLimit(lim *syscall.Rlimit) {}
diff --git a/contrib/go/_std_1.21/src/os/types_windows.go b/contrib/go/_std_1.21/src/os/types_windows.go
index 9a3d508783..effb0148df 100644
--- a/contrib/go/_std_1.21/src/os/types_windows.go
+++ b/contrib/go/_std_1.21/src/os/types_windows.go
@@ -141,7 +141,23 @@ func (fs *fileStat) Mode() (m FileMode) {
m |= ModeDevice | ModeCharDevice
}
if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 && m&ModeType == 0 {
- m |= ModeIrregular
+ if fs.ReparseTag == windows.IO_REPARSE_TAG_DEDUP {
+ // If the Data Deduplication service is enabled on Windows Server, its
+ // Optimization job may convert regular files to IO_REPARSE_TAG_DEDUP
+ // whenever that job runs.
+ //
+ // However, DEDUP reparse points remain similar in most respects to
+ // regular files: they continue to support random-access reads and writes
+ // of persistent data, and they shouldn't add unexpected latency or
+ // unavailability in the way that a network filesystem might.
+ //
+ // Go programs may use ModeIrregular to filter out unusual files (such as
+ // raw device files on Linux, POSIX FIFO special files, and so on), so
+ // to avoid files changing unpredictably from regular to irregular we will
+ // consider DEDUP files to be close enough to regular to treat as such.
+ } else {
+ m |= ModeIrregular
+ }
}
return m
}
diff --git a/contrib/go/_std_1.21/src/os/ya.make b/contrib/go/_std_1.21/src/os/ya.make
index dc812bdd07..8c4c417f82 100644
--- a/contrib/go/_std_1.21/src/os/ya.make
+++ b/contrib/go/_std_1.21/src/os/ya.make
@@ -29,8 +29,6 @@ ELSEIF (OS_LINUX AND ARCH_X86_64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -71,8 +69,6 @@ ELSEIF (OS_LINUX AND ARCH_ARM64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -113,8 +109,6 @@ ELSEIF (OS_LINUX AND ARCH_AARCH64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -154,8 +148,6 @@ ELSEIF (OS_DARWIN AND ARCH_X86_64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
@@ -195,8 +187,6 @@ ELSEIF (OS_DARWIN AND ARCH_ARM64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
@@ -236,8 +226,6 @@ ELSEIF (OS_DARWIN AND ARCH_AARCH64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
diff --git a/contrib/go/_std_1.21/src/path/filepath/path.go b/contrib/go/_std_1.21/src/path/filepath/path.go
index ca1d8b3116..3bf3ff6b89 100644
--- a/contrib/go/_std_1.21/src/path/filepath/path.go
+++ b/contrib/go/_std_1.21/src/path/filepath/path.go
@@ -15,7 +15,6 @@ import (
"errors"
"io/fs"
"os"
- "runtime"
"sort"
"strings"
)
@@ -167,21 +166,7 @@ func Clean(path string) string {
out.append('.')
}
- if runtime.GOOS == "windows" && out.volLen == 0 && out.buf != nil {
- // If a ':' appears in the path element at the start of a Windows path,
- // insert a .\ at the beginning to avoid converting relative paths
- // like a/../c: into c:.
- for _, c := range out.buf {
- if os.IsPathSeparator(c) {
- break
- }
- if c == ':' {
- out.prepend('.', Separator)
- break
- }
- }
- }
-
+ postClean(&out) // avoid creating absolute paths on Windows
return FromSlash(out.string())
}
diff --git a/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go b/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go
new file mode 100644
index 0000000000..db69f0228b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go
@@ -0,0 +1,9 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows
+
+package filepath
+
+func postClean(out *lazybuf) {}
diff --git a/contrib/go/_std_1.21/src/path/filepath/path_windows.go b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
index 4dca9e0f55..eacab0e5ce 100644
--- a/contrib/go/_std_1.21/src/path/filepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
@@ -5,6 +5,8 @@
package filepath
import (
+ "internal/safefilepath"
+ "os"
"strings"
"syscall"
)
@@ -20,34 +22,6 @@ func toUpper(c byte) byte {
return c
}
-// isReservedName reports if name is a Windows reserved device name or a console handle.
-// It does not detect names with an extension, which are also reserved on some Windows versions.
-//
-// For details, search for PRN in
-// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
-func isReservedName(name string) bool {
- if 3 <= len(name) && len(name) <= 4 {
- switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
- case "CON", "PRN", "AUX", "NUL":
- return len(name) == 3
- case "COM", "LPT":
- return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
- }
- }
- // Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
- // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
- //
- // While CONIN$ and CONOUT$ aren't documented as being files,
- // they behave the same as CON. For example, ./CONIN$ also opens the console input.
- if len(name) == 6 && name[5] == '$' && strings.EqualFold(name, "CONIN$") {
- return true
- }
- if len(name) == 7 && name[6] == '$' && strings.EqualFold(name, "CONOUT$") {
- return true
- }
- return false
-}
-
func isLocal(path string) bool {
if path == "" {
return false
@@ -68,25 +42,8 @@ func isLocal(path string) bool {
if part == "." || part == ".." {
hasDots = true
}
- // Trim the extension and look for a reserved name.
- base, _, hasExt := strings.Cut(part, ".")
- if isReservedName(base) {
- if !hasExt {
- return false
- }
- // The path element is a reserved name with an extension. Some Windows
- // versions consider this a reserved name, while others do not. Use
- // FullPath to see if the name is reserved.
- //
- // FullPath will convert references to reserved device names to their
- // canonical form: \\.\${DEVICE_NAME}
- //
- // FullPath does not perform this conversion for paths which contain
- // a reserved device name anywhere other than in the last element,
- // so check the part rather than the full path.
- if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
- return false
- }
+ if safefilepath.IsReservedName(part) {
+ return false
}
}
if hasDots {
@@ -118,40 +75,93 @@ func IsAbs(path string) (b bool) {
// volumeNameLen returns length of the leading volume name on Windows.
// It returns 0 elsewhere.
//
-// See: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
+// See:
+// https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
+// https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
func volumeNameLen(path string) int {
- if len(path) < 2 {
- return 0
- }
- // with drive letter
- c := path[0]
- if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
+ switch {
+ case len(path) >= 2 && path[1] == ':':
+ // Path starts with a drive letter.
+ //
+ // Not all Windows functions necessarily enforce the requirement that
+ // drive letters be in the set A-Z, and we don't try to here.
+ //
+ // We don't handle the case of a path starting with a non-ASCII character,
+ // in which case the "drive letter" might be multiple bytes long.
return 2
- }
- // UNC and DOS device paths start with two slashes.
- if !isSlash(path[0]) || !isSlash(path[1]) {
+
+ case len(path) == 0 || !isSlash(path[0]):
+ // Path does not have a volume component.
return 0
+
+ case pathHasPrefixFold(path, `\\.\UNC`):
+ // We're going to treat the UNC host and share as part of the volume
+ // prefix for historical reasons, but this isn't really principled;
+ // Windows's own GetFullPathName will happily remove the first
+ // component of the path in this space, converting
+ // \\.\unc\a\b\..\c into \\.\unc\a\c.
+ return uncLen(path, len(`\\.\UNC\`))
+
+ case pathHasPrefixFold(path, `\\.`) ||
+ pathHasPrefixFold(path, `\\?`) || pathHasPrefixFold(path, `\??`):
+ // Path starts with \\.\, and is a Local Device path; or
+ // path starts with \\?\ or \??\ and is a Root Local Device path.
+ //
+ // We treat the next component after the \\.\ prefix as
+ // part of the volume name, which means Clean(`\\?\c:\`)
+ // won't remove the trailing \. (See #64028.)
+ if len(path) == 3 {
+ return 3 // exactly \\.
+ }
+ _, rest, ok := cutPath(path[4:])
+ if !ok {
+ return len(path)
+ }
+ return len(path) - len(rest) - 1
+
+ case len(path) >= 2 && isSlash(path[1]):
+ // Path starts with \\, and is a UNC path.
+ return uncLen(path, 2)
}
- rest := path[2:]
- p1, rest, _ := cutPath(rest)
- p2, rest, ok := cutPath(rest)
- if !ok {
- return len(path)
+ return 0
+}
+
+// pathHasPrefixFold tests whether the path s begins with prefix,
+// ignoring case and treating all path separators as equivalent.
+// If s is longer than prefix, then s[len(prefix)] must be a path separator.
+func pathHasPrefixFold(s, prefix string) bool {
+ if len(s) < len(prefix) {
+ return false
}
- if p1 != "." && p1 != "?" {
- // This is a UNC path: \\${HOST}\${SHARE}\
- return len(path) - len(rest) - 1
+ for i := 0; i < len(prefix); i++ {
+ if isSlash(prefix[i]) {
+ if !isSlash(s[i]) {
+ return false
+ }
+ } else if toUpper(prefix[i]) != toUpper(s[i]) {
+ return false
+ }
}
- // This is a DOS device path.
- if len(p2) == 3 && toUpper(p2[0]) == 'U' && toUpper(p2[1]) == 'N' && toUpper(p2[2]) == 'C' {
- // This is a DOS device path that links to a UNC: \\.\UNC\${HOST}\${SHARE}\
- _, rest, _ = cutPath(rest) // host
- _, rest, ok = cutPath(rest) // share
- if !ok {
- return len(path)
+ if len(s) > len(prefix) && !isSlash(s[len(prefix)]) {
+ return false
+ }
+ return true
+}
+
+// uncLen returns the length of the volume prefix of a UNC path.
+// prefixLen is the prefix prior to the start of the UNC host;
+// for example, for "//host/share", the prefixLen is len("//")==2.
+func uncLen(path string, prefixLen int) int {
+ count := 0
+ for i := prefixLen; i < len(path); i++ {
+ if isSlash(path[i]) {
+ count++
+ if count == 2 {
+ return i
+ }
}
}
- return len(path) - len(rest) - 1
+ return len(path)
}
// cutPath slices path around the first path separator.
@@ -238,6 +248,12 @@ func join(elem []string) string {
for len(e) > 0 && isSlash(e[0]) {
e = e[1:]
}
+ // If the path is \ and the next path element is ??,
+ // add an extra .\ to create \.\?? rather than \??\
+ // (a Root Local Device path).
+ if b.Len() == 1 && pathHasPrefixFold(e, "??") {
+ b.WriteString(`.\`)
+ }
case lastChar == ':':
// If the path ends in a colon, keep the path relative to the current directory
// on a drive and don't add a separator. Preserve leading slashes in the next
@@ -304,3 +320,29 @@ func isUNC(path string) bool {
func sameWord(a, b string) bool {
return strings.EqualFold(a, b)
}
+
+// postClean adjusts the results of Clean to avoid turning a relative path
+// into an absolute or rooted one.
+func postClean(out *lazybuf) {
+ if out.volLen != 0 || out.buf == nil {
+ return
+ }
+ // If a ':' appears in the path element at the start of a path,
+ // insert a .\ at the beginning to avoid converting relative paths
+ // like a/../c: into c:.
+ for _, c := range out.buf {
+ if os.IsPathSeparator(c) {
+ break
+ }
+ if c == ':' {
+ out.prepend('.', Separator)
+ return
+ }
+ }
+ // If a path begins with \??\, insert a \. at the beginning
+ // to avoid converting paths like \a\..\??\c:\x into \??\c:\x
+ // (equivalent to c:\x).
+ if len(out.buf) >= 3 && os.IsPathSeparator(out.buf[0]) && out.buf[1] == '?' && out.buf[2] == '?' {
+ out.prepend(Separator, '.')
+ }
+}
diff --git a/contrib/go/_std_1.21/src/path/filepath/ya.make b/contrib/go/_std_1.21/src/path/filepath/ya.make
index 4b6a0333a7..9d04957bac 100644
--- a/contrib/go/_std_1.21/src/path/filepath/ya.make
+++ b/contrib/go/_std_1.21/src/path/filepath/ya.make
@@ -6,6 +6,7 @@ ELSEIF (OS_LINUX AND ARCH_X86_64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -14,6 +15,7 @@ ELSEIF (OS_LINUX AND ARCH_ARM64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -22,6 +24,7 @@ ELSEIF (OS_LINUX AND ARCH_AARCH64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -30,6 +33,7 @@ ELSEIF (OS_DARWIN AND ARCH_X86_64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -38,6 +42,7 @@ ELSEIF (OS_DARWIN AND ARCH_ARM64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -46,6 +51,7 @@ ELSEIF (OS_DARWIN AND ARCH_AARCH64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
index f254622f23..e319094a45 100644
--- a/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
@@ -7,12 +7,17 @@
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+// Use a local trampoline, to avoid taking the address of a dynamically exported
+// function.
TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
MOVQ _crosscall2_ptr(SB), AX
- MOVQ $crosscall2(SB), BX
+ MOVQ $crosscall2_trampoline<>(SB), BX
MOVQ BX, (AX)
RET
+TEXT crosscall2_trampoline<>(SB),NOSPLIT,$0-0
+ JMP crosscall2(SB)
+
// Called by C code generated by cmd/cgo.
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
// Saves C callee-saved registers and calls cgocallback with three arguments.
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
index ce8909b492..5492dc142c 100644
--- a/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
@@ -7,12 +7,17 @@
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+// Use a local trampoline, to avoid taking the address of a dynamically exported
+// function.
TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
MOVD _crosscall2_ptr(SB), R1
- MOVD $crosscall2(SB), R2
+ MOVD $crosscall2_trampoline<>(SB), R2
MOVD R2, (R1)
RET
+TEXT crosscall2_trampoline<>(SB),NOSPLIT,$0-0
+ JMP crosscall2(SB)
+
// Called by C code generated by cmd/cgo.
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
// Saves C callee-saved registers and calls cgocallback with three arguments.
diff --git a/contrib/go/_std_1.21/src/runtime/extern.go b/contrib/go/_std_1.21/src/runtime/extern.go
index 26dcf0bd52..de4a0ca2da 100644
--- a/contrib/go/_std_1.21/src/runtime/extern.go
+++ b/contrib/go/_std_1.21/src/runtime/extern.go
@@ -55,6 +55,13 @@ It is a comma-separated list of name=val pairs setting these named variables:
cgocheck mode can be enabled using GOEXPERIMENT (which
requires a rebuild), see https://pkg.go.dev/internal/goexperiment for details.
+ disablethp: setting disablethp=1 on Linux disables transparent huge pages for the heap.
+ It has no effect on other platforms. disablethp is meant for compatibility with versions
+ of Go before 1.21, which stopped working around a Linux kernel default that can result
+ in significant memory overuse. See https://go.dev/issue/64332. This setting will be
+ removed in a future release, so operators should tweak their Linux configuration to suit
+ their needs before then. See https://go.dev/doc/gc-guide#Linux_transparent_huge_pages.
+
dontfreezetheworld: by default, the start of a fatal panic or throw
"freezes the world", preempting all threads to stop all running
goroutines, which makes it possible to traceback all goroutines, and
diff --git a/contrib/go/_std_1.21/src/runtime/malloc.go b/contrib/go/_std_1.21/src/runtime/malloc.go
index 44479cc2be..b2026ad0dc 100644
--- a/contrib/go/_std_1.21/src/runtime/malloc.go
+++ b/contrib/go/_std_1.21/src/runtime/malloc.go
@@ -853,6 +853,10 @@ retry:
//
// The heap lock must not be held over this operation, since it will briefly acquire
// the heap lock.
+//
+// Must be called on the system stack because it acquires the heap lock.
+//
+//go:systemstack
func (h *mheap) enableMetadataHugePages() {
// Enable huge pages for page structure.
h.pages.enableChunkHugePages()
diff --git a/contrib/go/_std_1.21/src/runtime/map.go b/contrib/go/_std_1.21/src/runtime/map.go
index 6b85681447..22aeb86847 100644
--- a/contrib/go/_std_1.21/src/runtime/map.go
+++ b/contrib/go/_std_1.21/src/runtime/map.go
@@ -1481,12 +1481,24 @@ func moveToBmap(t *maptype, h *hmap, dst *bmap, pos int, src *bmap) (*bmap, int)
dst.tophash[pos] = src.tophash[i]
if t.IndirectKey() {
- *(*unsafe.Pointer)(dstK) = *(*unsafe.Pointer)(srcK)
+ srcK = *(*unsafe.Pointer)(srcK)
+ if t.NeedKeyUpdate() {
+ kStore := newobject(t.Key)
+ typedmemmove(t.Key, kStore, srcK)
+ srcK = kStore
+ }
+ // Note: if NeedKeyUpdate is false, then the memory
+ // used to store the key is immutable, so we can share
+ // it between the original map and its clone.
+ *(*unsafe.Pointer)(dstK) = srcK
} else {
typedmemmove(t.Key, dstK, srcK)
}
if t.IndirectElem() {
- *(*unsafe.Pointer)(dstEle) = *(*unsafe.Pointer)(srcEle)
+ srcEle = *(*unsafe.Pointer)(srcEle)
+ eStore := newobject(t.Elem)
+ typedmemmove(t.Elem, eStore, srcEle)
+ *(*unsafe.Pointer)(dstEle) = eStore
} else {
typedmemmove(t.Elem, dstEle, srcEle)
}
@@ -1510,14 +1522,14 @@ func mapclone2(t *maptype, src *hmap) *hmap {
fatal("concurrent map clone and map write")
}
- if src.B == 0 {
+ if src.B == 0 && !(t.IndirectKey() && t.NeedKeyUpdate()) && !t.IndirectElem() {
+ // Quick copy for small maps.
dst.buckets = newobject(t.Bucket)
dst.count = src.count
typedmemmove(t.Bucket, dst.buckets, src.buckets)
return dst
}
- //src.B != 0
if dst.B == 0 {
dst.buckets = newobject(t.Bucket)
}
@@ -1565,6 +1577,8 @@ func mapclone2(t *maptype, src *hmap) *hmap {
continue
}
+ // oldB < dst.B, so a single source bucket may go to multiple destination buckets.
+ // Process entries one at a time.
for srcBmap != nil {
// move from oldBlucket to new bucket
for i := uintptr(0); i < bucketCnt; i++ {
diff --git a/contrib/go/_std_1.21/src/runtime/mem_linux.go b/contrib/go/_std_1.21/src/runtime/mem_linux.go
index c9823d3011..d63c38c209 100644
--- a/contrib/go/_std_1.21/src/runtime/mem_linux.go
+++ b/contrib/go/_std_1.21/src/runtime/mem_linux.go
@@ -170,4 +170,12 @@ func sysMapOS(v unsafe.Pointer, n uintptr) {
print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
throw("runtime: cannot map pages in arena address space")
}
+
+ // Disable huge pages if the GODEBUG for it is set.
+ //
+ // Note that there are a few sysHugePage calls that can override this, but
+ // they're all for GC metadata.
+ if debug.disablethp != 0 {
+ sysNoHugePageOS(v, n)
+ }
}
diff --git a/contrib/go/_std_1.21/src/runtime/mgc.go b/contrib/go/_std_1.21/src/runtime/mgc.go
index de5ae0ae00..a12dbfe9df 100644
--- a/contrib/go/_std_1.21/src/runtime/mgc.go
+++ b/contrib/go/_std_1.21/src/runtime/mgc.go
@@ -1186,7 +1186,9 @@ func gcMarkTermination() {
// Enable huge pages on some metadata if we cross a heap threshold.
if gcController.heapGoal() > minHeapForMetadataHugePages {
- mheap_.enableMetadataHugePages()
+ systemstack(func() {
+ mheap_.enableMetadataHugePages()
+ })
}
semrelease(&worldsema)
diff --git a/contrib/go/_std_1.21/src/runtime/mgcscavenge.go b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
index 4c6d6be4f0..659ca8df2e 100644
--- a/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
+++ b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
@@ -1145,21 +1145,11 @@ func (s *scavengeIndex) alloc(ci chunkIdx, npages uint) {
// Mark that we're considering this chunk as backed by huge pages.
sc.setHugePage()
- // Collapse dense chunks into huge pages and mark that
- // we did that, but only if we're not allocating to
- // use the entire chunk. If we're allocating an entire chunk,
- // this is likely part of a much bigger allocation. For
- // instance, if the caller is allocating a 1 GiB slice of bytes, we
- // don't want to go and manually collapse all those pages; we want
- // them to be demand-paged. If the caller is actually going to use
- // all that memory, it'll naturally get backed by huge pages later.
- //
- // This also avoids having sysHugePageCollapse fail. On Linux,
- // the call requires that some part of the huge page being collapsed
- // is already paged in.
- if !s.test && npages < pallocChunkPages {
- sysHugePageCollapse(unsafe.Pointer(chunkBase(ci)), pallocChunkBytes)
- }
+ // TODO(mknyszek): Consider eagerly backing memory with huge pages
+ // here. In the past we've attempted to use sysHugePageCollapse
+ // (which uses MADV_COLLAPSE on Linux, and is unsupported elswhere)
+ // for this purpose, but that caused performance issues in production
+ // environments.
}
s.chunks[ci].store(sc)
}
diff --git a/contrib/go/_std_1.21/src/runtime/mpagealloc.go b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
index 3e789ab85c..2861fa93eb 100644
--- a/contrib/go/_std_1.21/src/runtime/mpagealloc.go
+++ b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
@@ -437,6 +437,10 @@ func (p *pageAlloc) grow(base, size uintptr) {
//
// The heap lock must not be held over this operation, since it will briefly acquire
// the heap lock.
+//
+// Must be called on the system stack because it acquires the heap lock.
+//
+//go:systemstack
func (p *pageAlloc) enableChunkHugePages() {
// Grab the heap lock to turn on huge pages for new chunks and clone the current
// heap address space ranges.
diff --git a/contrib/go/_std_1.21/src/runtime/mstats.go b/contrib/go/_std_1.21/src/runtime/mstats.go
index 9cdc565137..308bed67d7 100644
--- a/contrib/go/_std_1.21/src/runtime/mstats.go
+++ b/contrib/go/_std_1.21/src/runtime/mstats.go
@@ -367,6 +367,11 @@ func ReadMemStats(m *MemStats) {
startTheWorld()
}
+// doubleCheckReadMemStats controls a double-check mode for ReadMemStats that
+// ensures consistency between the values that ReadMemStats is using and the
+// runtime-internal stats.
+var doubleCheckReadMemStats = false
+
// readmemstats_m populates stats for internal runtime values.
//
// The world must be stopped.
@@ -441,56 +446,65 @@ func readmemstats_m(stats *MemStats) {
heapGoal := gcController.heapGoal()
- // The world is stopped, so the consistent stats (after aggregation)
- // should be identical to some combination of memstats. In particular:
- //
- // * memstats.heapInUse == inHeap
- // * memstats.heapReleased == released
- // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
- // * memstats.totalAlloc == totalAlloc
- // * memstats.totalFree == totalFree
- //
- // Check if that's actually true.
- //
- // TODO(mknyszek): Maybe don't throw here. It would be bad if a
- // bug in otherwise benign accounting caused the whole application
- // to crash.
- if gcController.heapInUse.load() != uint64(consStats.inHeap) {
- print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
- print("runtime: consistent value=", consStats.inHeap, "\n")
- throw("heapInUse and consistent stats are not equal")
- }
- if gcController.heapReleased.load() != uint64(consStats.released) {
- print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
- print("runtime: consistent value=", consStats.released, "\n")
- throw("heapReleased and consistent stats are not equal")
- }
- heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
- consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
- if heapRetained != consRetained {
- print("runtime: global value=", heapRetained, "\n")
- print("runtime: consistent value=", consRetained, "\n")
- throw("measures of the retained heap are not equal")
- }
- if gcController.totalAlloc.Load() != totalAlloc {
- print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
- print("runtime: consistent value=", totalAlloc, "\n")
- throw("totalAlloc and consistent stats are not equal")
- }
- if gcController.totalFree.Load() != totalFree {
- print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
- print("runtime: consistent value=", totalFree, "\n")
- throw("totalFree and consistent stats are not equal")
- }
- // Also check that mappedReady lines up with totalMapped - released.
- // This isn't really the same type of "make sure consistent stats line up" situation,
- // but this is an opportune time to check.
- if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
- print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
- print("runtime: totalMapped=", totalMapped, "\n")
- print("runtime: released=", uint64(consStats.released), "\n")
- print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
- throw("mappedReady and other memstats are not equal")
+ if doubleCheckReadMemStats {
+ // Only check this if we're debugging. It would be bad to crash an application
+ // just because the debugging stats are wrong. We mostly rely on tests to catch
+ // these issues, and we enable the double check mode for tests.
+ //
+ // The world is stopped, so the consistent stats (after aggregation)
+ // should be identical to some combination of memstats. In particular:
+ //
+ // * memstats.heapInUse == inHeap
+ // * memstats.heapReleased == released
+ // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
+ // * memstats.totalAlloc == totalAlloc
+ // * memstats.totalFree == totalFree
+ //
+ // Check if that's actually true.
+ //
+ // Prevent sysmon and the tracer from skewing the stats since they can
+ // act without synchronizing with a STW. See #64401.
+ lock(&sched.sysmonlock)
+ lock(&trace.lock)
+ if gcController.heapInUse.load() != uint64(consStats.inHeap) {
+ print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
+ print("runtime: consistent value=", consStats.inHeap, "\n")
+ throw("heapInUse and consistent stats are not equal")
+ }
+ if gcController.heapReleased.load() != uint64(consStats.released) {
+ print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
+ print("runtime: consistent value=", consStats.released, "\n")
+ throw("heapReleased and consistent stats are not equal")
+ }
+ heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
+ consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
+ if heapRetained != consRetained {
+ print("runtime: global value=", heapRetained, "\n")
+ print("runtime: consistent value=", consRetained, "\n")
+ throw("measures of the retained heap are not equal")
+ }
+ if gcController.totalAlloc.Load() != totalAlloc {
+ print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
+ print("runtime: consistent value=", totalAlloc, "\n")
+ throw("totalAlloc and consistent stats are not equal")
+ }
+ if gcController.totalFree.Load() != totalFree {
+ print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
+ print("runtime: consistent value=", totalFree, "\n")
+ throw("totalFree and consistent stats are not equal")
+ }
+ // Also check that mappedReady lines up with totalMapped - released.
+ // This isn't really the same type of "make sure consistent stats line up" situation,
+ // but this is an opportune time to check.
+ if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
+ print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
+ print("runtime: totalMapped=", totalMapped, "\n")
+ print("runtime: released=", uint64(consStats.released), "\n")
+ print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
+ throw("mappedReady and other memstats are not equal")
+ }
+ unlock(&trace.lock)
+ unlock(&sched.sysmonlock)
}
// We've calculated all the values we need. Now, populate stats.
diff --git a/contrib/go/_std_1.21/src/runtime/os_windows.go b/contrib/go/_std_1.21/src/runtime/os_windows.go
index f5c2429a05..735a905b61 100644
--- a/contrib/go/_std_1.21/src/runtime/os_windows.go
+++ b/contrib/go/_std_1.21/src/runtime/os_windows.go
@@ -127,15 +127,8 @@ var (
_AddVectoredContinueHandler,
_ stdFunction
- // Use RtlGenRandom to generate cryptographically random data.
- // This approach has been recommended by Microsoft (see issue
- // 15589 for details).
- // The RtlGenRandom is not listed in advapi32.dll, instead
- // RtlGenRandom function can be found by searching for SystemFunction036.
- // Also some versions of Mingw cannot link to SystemFunction036
- // when building executable as Cgo. So load SystemFunction036
- // manually during runtime startup.
- _RtlGenRandom stdFunction
+ // Use ProcessPrng to generate cryptographically random data.
+ _ProcessPrng stdFunction
// Load ntdll.dll manually during startup, otherwise Mingw
// links wrong printf function to cgo executable (see issue
@@ -152,12 +145,12 @@ var (
)
var (
- advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0}
- kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0}
- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
+ bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0}
+ kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0}
+ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
+ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
+ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
+ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
)
// Function to be called by windows CreateThread
@@ -256,11 +249,11 @@ func loadOptionalSyscalls() {
}
_AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
- a32 := windowsLoadSystemLib(advapi32dll[:])
- if a32 == 0 {
- throw("advapi32.dll not found")
+ bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:])
+ if bcryptPrimitives == 0 {
+ throw("bcryptprimitives.dll not found")
}
- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
+ _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000"))
n32 := windowsLoadSystemLib(ntdlldll[:])
if n32 == 0 {
@@ -617,7 +610,7 @@ func initWine(k32 uintptr) {
//go:nosplit
func getRandomData(r []byte) {
n := 0
- if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
+ if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
n = len(r)
}
extendRandom(r, n)
diff --git a/contrib/go/_std_1.21/src/runtime/pprof/proto.go b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
index cdc4bd7c80..db9384eb21 100644
--- a/contrib/go/_std_1.21/src/runtime/pprof/proto.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
@@ -611,13 +611,14 @@ func (b *profileBuilder) emitLocation() uint64 {
b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC))
for _, frame := range b.deck.frames {
// Write out each line in frame expansion.
- funcID := uint64(b.funcs[frame.Function])
+ funcName := runtime_FrameSymbolName(&frame)
+ funcID := uint64(b.funcs[funcName])
if funcID == 0 {
funcID = uint64(len(b.funcs)) + 1
- b.funcs[frame.Function] = int(funcID)
+ b.funcs[funcName] = int(funcID)
newFuncs = append(newFuncs, newFunc{
id: funcID,
- name: runtime_FrameSymbolName(&frame),
+ name: funcName,
file: frame.File,
startLine: int64(runtime_FrameStartLine(&frame)),
})
diff --git a/contrib/go/_std_1.21/src/runtime/runtime.go b/contrib/go/_std_1.21/src/runtime/runtime.go
index 0822d0e805..15119cf5df 100644
--- a/contrib/go/_std_1.21/src/runtime/runtime.go
+++ b/contrib/go/_std_1.21/src/runtime/runtime.go
@@ -101,12 +101,17 @@ func (g *godebugInc) IncNonDefault() {
if newInc == nil {
return
}
- // If other goroutines are racing here, no big deal. One will win,
- // and all the inc functions will be using the same underlying
- // *godebug.Setting.
inc = new(func())
*inc = (*newInc)(g.name)
- g.inc.Store(inc)
+ if raceenabled {
+ racereleasemerge(unsafe.Pointer(&g.inc))
+ }
+ if !g.inc.CompareAndSwap(nil, inc) {
+ inc = g.inc.Load()
+ }
+ }
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&g.inc))
}
(*inc)()
}
diff --git a/contrib/go/_std_1.21/src/runtime/runtime1.go b/contrib/go/_std_1.21/src/runtime/runtime1.go
index 92a7e021ee..7174c63af3 100644
--- a/contrib/go/_std_1.21/src/runtime/runtime1.go
+++ b/contrib/go/_std_1.21/src/runtime/runtime1.go
@@ -309,6 +309,7 @@ type dbgVar struct {
var debug struct {
cgocheck int32
clobberfree int32
+ disablethp int32
dontfreezetheworld int32
efence int32
gccheckmark int32
@@ -342,6 +343,7 @@ var dbgvars = []*dbgVar{
{name: "allocfreetrace", value: &debug.allocfreetrace},
{name: "clobberfree", value: &debug.clobberfree},
{name: "cgocheck", value: &debug.cgocheck},
+ {name: "disablethp", value: &debug.disablethp},
{name: "dontfreezetheworld", value: &debug.dontfreezetheworld},
{name: "efence", value: &debug.efence},
{name: "gccheckmark", value: &debug.gccheckmark},