diff options
author | psydvl <psydvl@yandex-team.com> | 2024-07-10 11:16:37 +0300 |
---|---|---|
committer | psydvl <psydvl@yandex-team.com> | 2024-07-10 11:30:40 +0300 |
commit | 0281735672968c8e84def9279d2845af99cc2c44 (patch) | |
tree | 7e8fd347182958bf933e62447be05ed68377cbee | |
parent | 02dce8fb96150aa1b41f0ead67e108999556a4a8 (diff) | |
download | ydb-0281735672968c8e84def9279d2845af99cc2c44.tar.gz |
go: 1.22.1 -> 1.22.5
update fetch script
toolchain binaries update
fix instruction
go library update
codenv toolchain update pin
24c4d077a2fb5f87554c06c17f0a8f0947e710a2
23 files changed, 273 insertions, 109 deletions
diff --git a/build/external_resources/go_tools/go1.22.json b/build/external_resources/go_tools/go1.22.json index ea3fb2e254..b6fe74abe3 100644 --- a/build/external_resources/go_tools/go1.22.json +++ b/build/external_resources/go_tools/go1.22.json @@ -1,19 +1,19 @@ { "by_platform": { "darwin-arm64": { - "uri": "sbr:6067021677" + "uri": "sbr:6608868508" }, "darwin-x86_64": { - "uri": "sbr:6067013969" + "uri": "sbr:6608867118" }, "linux-x86_64": { - "uri": "sbr:6066996288" + "uri": "sbr:6608864313" }, "linux-aarch64": { - "uri": "sbr:6067006318" + "uri": "sbr:6608865495" }, "win32-x86_64": { - "uri": "sbr:6577190334" + "uri": "sbr:6608870313" } } } diff --git a/contrib/go/_std_1.22/src/crypto/tls/handshake_client.go b/contrib/go/_std_1.22/src/crypto/tls/handshake_client.go index f016e01b4b..08a2d47974 100644 --- a/contrib/go/_std_1.22/src/crypto/tls/handshake_client.go +++ b/contrib/go/_std_1.22/src/crypto/tls/handshake_client.go @@ -526,7 +526,7 @@ func (hs *clientHandshakeState) pickCipherSuite() error { return errors.New("tls: server chose an unconfigured cipher suite") } - if hs.c.config.CipherSuites == nil && rsaKexCiphers[hs.suite.id] { + if hs.c.config.CipherSuites == nil && !needFIPS() && rsaKexCiphers[hs.suite.id] { tlsrsakex.IncNonDefault() } diff --git a/contrib/go/_std_1.22/src/crypto/tls/handshake_server.go b/contrib/go/_std_1.22/src/crypto/tls/handshake_server.go index 8129e9c616..4e84aa9d8f 100644 --- a/contrib/go/_std_1.22/src/crypto/tls/handshake_server.go +++ b/contrib/go/_std_1.22/src/crypto/tls/handshake_server.go @@ -370,7 +370,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error { } c.cipherSuite = hs.suite.id - if c.config.CipherSuites == nil && rsaKexCiphers[hs.suite.id] { + if c.config.CipherSuites == nil && !needFIPS() && rsaKexCiphers[hs.suite.id] { tlsrsakex.IncNonDefault() } diff --git a/contrib/go/_std_1.22/src/crypto/x509/x509.go b/contrib/go/_std_1.22/src/crypto/x509/x509.go index f33283b559..15b3b9ed35 100644 --- a/contrib/go/_std_1.22/src/crypto/x509/x509.go +++ b/contrib/go/_std_1.22/src/crypto/x509/x509.go @@ -780,6 +780,7 @@ type Certificate struct { PolicyIdentifiers []asn1.ObjectIdentifier // Policies contains all policy identifiers included in the certificate. + // In Go 1.22, encoding/gob cannot handle and ignores this field. Policies []OID } diff --git a/contrib/go/_std_1.22/src/go/types/initorder.go b/contrib/go/_std_1.22/src/go/types/initorder.go index 9ee176fbdb..a8d8f26b22 100644 --- a/contrib/go/_std_1.22/src/go/types/initorder.go +++ b/contrib/go/_std_1.22/src/go/types/initorder.go @@ -307,6 +307,14 @@ func (a nodeQueue) Swap(i, j int) { func (a nodeQueue) Less(i, j int) bool { x, y := a[i], a[j] + + // Prioritize all constants before non-constants. See go.dev/issue/66575/. + _, xConst := x.obj.(*Const) + _, yConst := y.obj.(*Const) + if xConst != yConst { + return xConst + } + // nodes are prioritized by number of incoming dependencies (1st key) // and source order (2nd key) return x.ndeps < y.ndeps || x.ndeps == y.ndeps && x.obj.order() < y.obj.order() diff --git a/contrib/go/_std_1.22/src/go/types/stmt.go b/contrib/go/_std_1.22/src/go/types/stmt.go index 80f3ac75da..bb203f130c 100644 --- a/contrib/go/_std_1.22/src/go/types/stmt.go +++ b/contrib/go/_std_1.22/src/go/types/stmt.go @@ -893,7 +893,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *ast.RangeStmt) { lhs := [2]Expr{sKey, sValue} // sKey, sValue may be nil rhs := [2]Type{key, val} // key, val may be nil - constIntRange := x.mode == constant_ && isInteger(x.typ) + rangeOverInt := isInteger(x.typ) if isDef { // short variable declaration @@ -918,19 +918,27 @@ func (check *Checker) rangeStmt(inner stmtContext, s *ast.RangeStmt) { check.errorf(lhs, InvalidSyntaxTree, "cannot declare %s", lhs) obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable } + assert(obj.typ == nil) - // initialize lhs variable - if constIntRange { - check.initVar(obj, &x, "range clause") - } else if typ := rhs[i]; typ != nil { - x.mode = value - x.expr = lhs // we don't have a better rhs expression to use here - x.typ = typ - check.initVar(obj, &x, "assignment") // error is on variable, use "assignment" not "range clause" - } else { + // initialize lhs iteration variable, if any + typ := rhs[i] + if typ == nil { obj.typ = Typ[Invalid] obj.used = true // don't complain about unused variable + continue + } + + if rangeOverInt { + assert(i == 0) // at most one iteration variable (rhs[1] == nil for rangeOverInt) + check.initVar(obj, &x, "range clause") + } else { + var y operand + y.mode = value + y.expr = lhs // we don't have a better rhs expression to use here + y.typ = typ + check.initVar(obj, &y, "assignment") // error is on variable, use "assignment" not "range clause" } + assert(obj.typ != nil) } // declare variables @@ -949,21 +957,36 @@ func (check *Checker) rangeStmt(inner stmtContext, s *ast.RangeStmt) { continue } - if constIntRange { + // assign to lhs iteration variable, if any + typ := rhs[i] + if typ == nil { + continue + } + + if rangeOverInt { + assert(i == 0) // at most one iteration variable (rhs[1] == nil for rangeOverInt) check.assignVar(lhs, nil, &x, "range clause") - } else if typ := rhs[i]; typ != nil { - x.mode = value - x.expr = lhs // we don't have a better rhs expression to use here - x.typ = typ - check.assignVar(lhs, nil, &x, "assignment") // error is on variable, use "assignment" not "range clause" + // If the assignment succeeded, if x was untyped before, it now + // has a type inferred via the assignment. It must be an integer. + // (go.dev/issues/67027) + if x.mode != invalid && !isInteger(x.typ) { + check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ) + } + } else { + var y operand + y.mode = value + y.expr = lhs // we don't have a better rhs expression to use here + y.typ = typ + check.assignVar(lhs, nil, &y, "assignment") // error is on variable, use "assignment" not "range clause" } } - } else if constIntRange { + } else if rangeOverInt { // If we don't have any iteration variables, we still need to // check that a (possibly untyped) integer range expression x // is valid. // We do this by checking the assignment _ = x. This ensures - // that an untyped x can be converted to a value of type int. + // that an untyped x can be converted to a value of its default + // type (rune or int). check.assignment(&x, nil, "range clause") } @@ -993,6 +1016,7 @@ func rangeKeyVal(typ Type, allowVersion func(goVersion) bool) (key, val Type, ca return Typ[Int], universeRune, "", false, true // use 'rune' name } if isInteger(typ) { + // untyped numeric constants may be representable as integer values if allowVersion != nil && !allowVersion(go1_22) { return bad("requires go1.22 or later") } diff --git a/contrib/go/_std_1.22/src/go/types/subst.go b/contrib/go/_std_1.22/src/go/types/subst.go index 1934ebab2b..178f717283 100644 --- a/contrib/go/_std_1.22/src/go/types/subst.go +++ b/contrib/go/_std_1.22/src/go/types/subst.go @@ -97,6 +97,18 @@ func (subst *subster) typ(typ Type) Type { case *Basic: // nothing to do + case *Alias: + rhs := subst.typ(t.fromRHS) + if rhs != t.fromRHS { + // This branch cannot be reached because the RHS of an alias + // may only contain type parameters of an enclosing function. + // Such function bodies are never "instantiated" and thus + // substitution is not called on locally declared alias types. + // TODO(gri) adjust once parameterized aliases are supported + panic("unreachable for unparameterized aliases") + // return subst.check.newAlias(t.obj, rhs) + } + case *Array: elem := subst.typOrNil(t.elem) if elem != t.elem { diff --git a/contrib/go/_std_1.22/src/internal/buildcfg/zbootstrap.go b/contrib/go/_std_1.22/src/internal/buildcfg/zbootstrap.go index 79bae30ac6..c4a47af3ef 100644 --- a/contrib/go/_std_1.22/src/internal/buildcfg/zbootstrap.go +++ b/contrib/go/_std_1.22/src/internal/buildcfg/zbootstrap.go @@ -13,6 +13,6 @@ const defaultGOPPC64 = `power8` const defaultGOEXPERIMENT = `` const defaultGO_EXTLINK_ENABLED = `` const defaultGO_LDSO = `` -const version = `go1.22.1` +const version = `go1.22.5` const defaultGOOS = runtime.GOOS const defaultGOARCH = runtime.GOARCH diff --git a/contrib/go/_std_1.22/src/internal/godebugs/table.go b/contrib/go/_std_1.22/src/internal/godebugs/table.go index a0a0672966..11c5b7d6fd 100644 --- a/contrib/go/_std_1.22/src/internal/godebugs/table.go +++ b/contrib/go/_std_1.22/src/internal/godebugs/table.go @@ -42,6 +42,7 @@ var All = []Info{ {Name: "multipartmaxparts", Package: "mime/multipart"}, {Name: "multipathtcp", Package: "net"}, {Name: "netdns", Package: "net", Opaque: true}, + {Name: "netedns0", Package: "net", Changed: 19, Old: "0"}, {Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"}, {Name: "randautoseed", Package: "math/rand"}, {Name: "tarinsecurepath", Package: "archive/tar"}, diff --git a/contrib/go/_std_1.22/src/net/dnsclient_unix.go b/contrib/go/_std_1.22/src/net/dnsclient_unix.go index c291d5eb4f..8821641a01 100644 --- a/contrib/go/_std_1.22/src/net/dnsclient_unix.go +++ b/contrib/go/_std_1.22/src/net/dnsclient_unix.go @@ -16,6 +16,7 @@ import ( "context" "errors" "internal/bytealg" + "internal/godebug" "internal/itoa" "io" "os" @@ -51,6 +52,9 @@ var ( errServerTemporarilyMisbehaving = errors.New("server misbehaving") ) +// netedns0 controls whether we send an EDNS0 additional header. +var netedns0 = godebug.New("netedns0") + func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byte, err error) { id = uint16(randInt()) b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true, AuthenticData: ad}) @@ -61,16 +65,20 @@ func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byt return 0, nil, nil, err } - // Accept packets up to maxDNSPacketSize. RFC 6891. - if err := b.StartAdditionals(); err != nil { - return 0, nil, nil, err - } - var rh dnsmessage.ResourceHeader - if err := rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false); err != nil { - return 0, nil, nil, err - } - if err := b.OPTResource(rh, dnsmessage.OPTResource{}); err != nil { - return 0, nil, nil, err + if netedns0.Value() == "0" { + netedns0.IncNonDefault() + } else { + // Accept packets up to maxDNSPacketSize. RFC 6891. + if err := b.StartAdditionals(); err != nil { + return 0, nil, nil, err + } + var rh dnsmessage.ResourceHeader + if err := rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false); err != nil { + return 0, nil, nil, err + } + if err := b.OPTResource(rh, dnsmessage.OPTResource{}); err != nil { + return 0, nil, nil, err + } } tcpReq, err = b.Finish() @@ -267,7 +275,9 @@ func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) dnsmessage if ahdr.Type == dnsmessage.TypeOPT { return ahdr.ExtendedRCode(hdr.RCode) } - p.SkipAdditional() + if err := p.SkipAdditional(); err != nil { + return hdr.RCode + } } } diff --git a/contrib/go/_std_1.22/src/net/http/h2_bundle.go b/contrib/go/_std_1.22/src/net/http/h2_bundle.go index ac41144d5b..c1a2e76ea4 100644 --- a/contrib/go/_std_1.22/src/net/http/h2_bundle.go +++ b/contrib/go/_std_1.22/src/net/http/h2_bundle.go @@ -1894,6 +1894,9 @@ func http2terminalReadFrameError(err error) bool { // returned error is ErrFrameTooLarge. Other errors may be of type // ConnectionError, StreamError, or anything else from the underlying // reader. +// +// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID +// indicates the stream responsible for the error. func (fr *http2Framer) ReadFrame() (http2Frame, error) { fr.errDetail = nil if fr.lastFrame != nil { @@ -2926,7 +2929,7 @@ func (fr *http2Framer) maxHeaderStringLen() int { // readMetaFrame returns 0 or more CONTINUATION frames from fr and // merge them into the provided hf and returns a MetaHeadersFrame // with the decoded hpack values. -func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFrame, error) { +func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (http2Frame, error) { if fr.AllowIllegalReads { return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") } @@ -2969,6 +2972,7 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr if size > remainSize { hdec.SetEmitEnabled(false) mh.Truncated = true + remainSize = 0 return } remainSize -= size @@ -2981,8 +2985,38 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr var hc http2headersOrContinuation = hf for { frag := hc.HeaderBlockFragment() + + // Avoid parsing large amounts of headers that we will then discard. + // If the sender exceeds the max header list size by too much, + // skip parsing the fragment and close the connection. + // + // "Too much" is either any CONTINUATION frame after we've already + // exceeded the max header list size (in which case remainSize is 0), + // or a frame whose encoded size is more than twice the remaining + // header list bytes we're willing to accept. + if int64(len(frag)) > int64(2*remainSize) { + if http2VerboseLogs { + log.Printf("http2: header list too large") + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return mh, http2ConnectionError(http2ErrCodeProtocol) + } + + // Also close the connection after any CONTINUATION frame following an + // invalid header, since we stop tracking the size of the headers after + // an invalid one. + if invalid != nil { + if http2VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return mh, http2ConnectionError(http2ErrCodeProtocol) + } + if _, err := hdec.Write(frag); err != nil { - return nil, http2ConnectionError(http2ErrCodeCompression) + return mh, http2ConnectionError(http2ErrCodeCompression) } if hc.HeadersEnded() { @@ -2999,7 +3033,7 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr mh.http2HeadersFrame.invalidate() if err := hdec.Close(); err != nil { - return nil, http2ConnectionError(http2ErrCodeCompression) + return mh, http2ConnectionError(http2ErrCodeCompression) } if invalid != nil { fr.errDetail = invalid @@ -5266,6 +5300,11 @@ func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool sc.goAway(http2ErrCodeFlowControl) return true case http2ConnectionError: + if res.f != nil { + if id := res.f.Header().StreamID; id > sc.maxClientStreamID { + sc.maxClientStreamID = id + } + } sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev) sc.goAway(http2ErrCode(ev)) return true // goAway will handle shutdown @@ -9712,7 +9751,7 @@ func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, http2StreamError{ StreamID: f.StreamID, diff --git a/contrib/go/_std_1.22/src/net/http/server.go b/contrib/go/_std_1.22/src/net/http/server.go index acac78bcd0..23a603a83d 100644 --- a/contrib/go/_std_1.22/src/net/http/server.go +++ b/contrib/go/_std_1.22/src/net/http/server.go @@ -1357,16 +1357,21 @@ func (cw *chunkWriter) writeHeader(p []byte) { // If the client wanted a 100-continue but we never sent it to // them (or, more strictly: we never finished reading their - // request body), don't reuse this connection because it's now - // in an unknown state: we might be sending this response at - // the same time the client is now sending its request body - // after a timeout. (Some HTTP clients send Expect: - // 100-continue but knowing that some servers don't support - // it, the clients set a timer and send the body later anyway) - // If we haven't seen EOF, we can't skip over the unread body - // because we don't know if the next bytes on the wire will be - // the body-following-the-timer or the subsequent request. - // See Issue 11549. + // request body), don't reuse this connection. + // + // This behavior was first added on the theory that we don't know + // if the next bytes on the wire are going to be the remainder of + // the request body or the subsequent request (see issue 11549), + // but that's not correct: If we keep using the connection, + // the client is required to send the request body whether we + // asked for it or not. + // + // We probably do want to skip reusing the connection in most cases, + // however. If the client is offering a large request body that we + // don't intend to use, then it's better to close the connection + // than to read the body. For now, assume that if we're sending + // headers, the handler is done reading the body and we should + // drop the connection if we haven't seen EOF. if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() { w.closeAfterReply = true } diff --git a/contrib/go/_std_1.22/src/net/http/transport.go b/contrib/go/_std_1.22/src/net/http/transport.go index 17067ac07c..66c54ef5ac 100644 --- a/contrib/go/_std_1.22/src/net/http/transport.go +++ b/contrib/go/_std_1.22/src/net/http/transport.go @@ -2336,17 +2336,12 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr return } resCode := resp.StatusCode - if continueCh != nil { - if resCode == 100 { - if trace != nil && trace.Got100Continue != nil { - trace.Got100Continue() - } - continueCh <- struct{}{} - continueCh = nil - } else if resCode >= 200 { - close(continueCh) - continueCh = nil + if continueCh != nil && resCode == StatusContinue { + if trace != nil && trace.Got100Continue != nil { + trace.Got100Continue() } + continueCh <- struct{}{} + continueCh = nil } is1xx := 100 <= resCode && resCode <= 199 // treat 101 as a terminal status, see issue 26161 @@ -2369,6 +2364,25 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr if resp.isProtocolSwitch() { resp.Body = newReadWriteCloserBody(pc.br, pc.conn) } + if continueCh != nil { + // We send an "Expect: 100-continue" header, but the server + // responded with a terminal status and no 100 Continue. + // + // If we're going to keep using the connection, we need to send the request body. + // Tell writeLoop to skip sending the body if we're going to close the connection, + // or to send it otherwise. + // + // The case where we receive a 101 Switching Protocols response is a bit + // ambiguous, since we don't know what protocol we're switching to. + // Conceivably, it's one that doesn't need us to send the body. + // Given that we'll send the body if ExpectContinueTimeout expires, + // be consistent and always send it if we aren't closing the connection. + if resp.Close || rc.req.Close { + close(continueCh) // don't send the body; the connection will close + } else { + continueCh <- struct{}{} // send the body + } + } resp.TLS = pc.tlsState return diff --git a/contrib/go/_std_1.22/src/net/net.go b/contrib/go/_std_1.22/src/net/net.go index c434c96bf8..2dd1b5865e 100644 --- a/contrib/go/_std_1.22/src/net/net.go +++ b/contrib/go/_std_1.22/src/net/net.go @@ -71,6 +71,12 @@ to print debugging information about its decisions. To force a particular resolver while also printing debugging information, join the two settings by a plus sign, as in GODEBUG=netdns=go+1. +The Go resolver will send an EDNS0 additional header with a DNS request, +to signal a willingness to accept a larger DNS packet size. +This can reportedly cause sporadic failures with the DNS server run +by some modems and routers. Setting GODEBUG=netedns0=0 will disable +sending the additional header. + On macOS, if Go code that uses the net package is built with -buildmode=c-archive, linking the resulting archive into a C program requires passing -lresolv when linking the C code. diff --git a/contrib/go/_std_1.22/src/net/netip/netip.go b/contrib/go/_std_1.22/src/net/netip/netip.go index 7a189e8e16..92cb57efef 100644 --- a/contrib/go/_std_1.22/src/net/netip/netip.go +++ b/contrib/go/_std_1.22/src/net/netip/netip.go @@ -508,6 +508,10 @@ func (ip Addr) hasZone() bool { // IsLinkLocalUnicast reports whether ip is a link-local unicast address. func (ip Addr) IsLinkLocalUnicast() bool { + if ip.Is4In6() { + ip = ip.Unmap() + } + // Dynamic Configuration of IPv4 Link-Local Addresses // https://datatracker.ietf.org/doc/html/rfc3927#section-2.1 if ip.Is4() { @@ -523,6 +527,10 @@ func (ip Addr) IsLinkLocalUnicast() bool { // IsLoopback reports whether ip is a loopback address. func (ip Addr) IsLoopback() bool { + if ip.Is4In6() { + ip = ip.Unmap() + } + // Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing) // https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3 if ip.Is4() { @@ -538,6 +546,10 @@ func (ip Addr) IsLoopback() bool { // IsMulticast reports whether ip is a multicast address. func (ip Addr) IsMulticast() bool { + if ip.Is4In6() { + ip = ip.Unmap() + } + // Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES) // https://datatracker.ietf.org/doc/html/rfc1112#section-4 if ip.Is4() { @@ -556,7 +568,7 @@ func (ip Addr) IsMulticast() bool { func (ip Addr) IsInterfaceLocalMulticast() bool { // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses) // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1 - if ip.Is6() { + if ip.Is6() && !ip.Is4In6() { return ip.v6u16(0)&0xff0f == 0xff01 } return false // zero value @@ -564,6 +576,10 @@ func (ip Addr) IsInterfaceLocalMulticast() bool { // IsLinkLocalMulticast reports whether ip is a link-local multicast address. func (ip Addr) IsLinkLocalMulticast() bool { + if ip.Is4In6() { + ip = ip.Unmap() + } + // IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24)) // https://datatracker.ietf.org/doc/html/rfc5771#section-4 if ip.Is4() { @@ -592,6 +608,10 @@ func (ip Addr) IsGlobalUnicast() bool { return false } + if ip.Is4In6() { + ip = ip.Unmap() + } + // Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses // and ULA IPv6 addresses are still considered "global unicast". if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) { @@ -609,6 +629,10 @@ func (ip Addr) IsGlobalUnicast() bool { // ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the // same as [net.IP.IsPrivate]. func (ip Addr) IsPrivate() bool { + if ip.Is4In6() { + ip = ip.Unmap() + } + // Match the stdlib's IsPrivate logic. if ip.Is4() { // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as diff --git a/contrib/go/_std_1.22/src/os/file_unix.go b/contrib/go/_std_1.22/src/os/file_unix.go index a527b23e4f..649ec3ebb5 100644 --- a/contrib/go/_std_1.22/src/os/file_unix.go +++ b/contrib/go/_std_1.22/src/os/file_unix.go @@ -157,7 +157,7 @@ const ( kindNonBlock // kindNoPoll means that we should not put the descriptor into // non-blocking mode, because we know it is not a pipe or FIFO. - // Used by openFdAt for directories. + // Used by openDirAt for directories. kindNoPoll ) @@ -256,7 +256,7 @@ func epipecheck(file *File, e error) { const DevNull = "/dev/null" // openFileNolog is the Unix implementation of OpenFile. -// Changes here should be reflected in openFdAt, if relevant. +// Changes here should be reflected in openDirAt, if relevant. func openFileNolog(name string, flag int, perm FileMode) (*File, error) { setSticky := false if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 { diff --git a/contrib/go/_std_1.22/src/os/removeall_at.go b/contrib/go/_std_1.22/src/os/removeall_at.go index 8ea5df4117..774ca15823 100644 --- a/contrib/go/_std_1.22/src/os/removeall_at.go +++ b/contrib/go/_std_1.22/src/os/removeall_at.go @@ -74,22 +74,7 @@ func removeAllFrom(parent *File, base string) error { if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES { return &PathError{Op: "unlinkat", Path: base, Err: err} } - - // Is this a directory we need to recurse into? - var statInfo syscall.Stat_t - statErr := ignoringEINTR(func() error { - return unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW) - }) - if statErr != nil { - if IsNotExist(statErr) { - return nil - } - return &PathError{Op: "fstatat", Path: base, Err: statErr} - } - if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR { - // Not a directory; return the error from the unix.Unlinkat. - return &PathError{Op: "unlinkat", Path: base, Err: err} - } + uErr := err // Remove the directory's entries. var recurseErr error @@ -98,11 +83,15 @@ func removeAllFrom(parent *File, base string) error { var respSize int // Open the directory to recurse into - file, err := openFdAt(parentFd, base) + file, err := openDirAt(parentFd, base) if err != nil { if IsNotExist(err) { return nil } + if err == syscall.ENOTDIR { + // Not a directory; return the error from the unix.Unlinkat. + return &PathError{Op: "unlinkat", Path: base, Err: uErr} + } recurseErr = &PathError{Op: "openfdat", Path: base, Err: err} break } @@ -168,16 +157,19 @@ func removeAllFrom(parent *File, base string) error { return &PathError{Op: "unlinkat", Path: base, Err: unlinkError} } -// openFdAt opens path relative to the directory in fd. -// Other than that this should act like openFileNolog. +// openDirAt opens a directory name relative to the directory referred to by +// the file descriptor dirfd. If name is anything but a directory (this +// includes a symlink to one), it should return an error. Other than that this +// should act like openFileNolog. +// // This acts like openFileNolog rather than OpenFile because // we are going to (try to) remove the file. // The contents of this file are not relevant for test caching. -func openFdAt(dirfd int, name string) (*File, error) { +func openDirAt(dirfd int, name string) (*File, error) { var r int for { var e error - r, e = unix.Openat(dirfd, name, O_RDONLY|syscall.O_CLOEXEC, 0) + r, e = unix.Openat(dirfd, name, O_RDONLY|syscall.O_CLOEXEC|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) if e == nil { break } diff --git a/contrib/go/_std_1.22/src/runtime/alg.go b/contrib/go/_std_1.22/src/runtime/alg.go index eaf9c91490..ef4f859c23 100644 --- a/contrib/go/_std_1.22/src/runtime/alg.go +++ b/contrib/go/_std_1.22/src/runtime/alg.go @@ -391,7 +391,7 @@ func alginit() { return } for i := range hashkey { - hashkey[i] = uintptr(rand()) | 1 // make sure these numbers are odd + hashkey[i] = uintptr(bootstrapRand()) | 1 // make sure these numbers are odd } } diff --git a/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_darwin.c b/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_darwin.c index 0a9038eb3b..28364c7420 100644 --- a/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_darwin.c +++ b/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_darwin.c @@ -15,6 +15,11 @@ x_cgo_getstackbound(uintptr bounds[2]) p = pthread_self(); addr = pthread_get_stackaddr_np(p); // high address (!) size = pthread_get_stacksize_np(p); + + // bounds points into the Go stack. TSAN can't see the synchronization + // in Go around stack reuse. + _cgo_tsan_acquire(); bounds[0] = (uintptr)addr - size; bounds[1] = (uintptr)addr; + _cgo_tsan_release(); } diff --git a/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_unix.c b/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_unix.c index f3fead9c9e..884281dc15 100644 --- a/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_unix.c +++ b/contrib/go/_std_1.22/src/runtime/cgo/gcc_stack_unix.c @@ -18,6 +18,9 @@ x_cgo_getstackbound(uintptr bounds[2]) void *addr; size_t size; + // Needed before pthread_getattr_np, too, since before glibc 2.32 + // it did not call pthread_attr_init in all cases (see #65625). + pthread_attr_init(&attr); #if defined(__GLIBC__) || (defined(__sun) && !defined(__illumos__)) // pthread_getattr_np is a GNU extension supported in glibc. // Solaris is not glibc but does support pthread_getattr_np @@ -25,16 +28,18 @@ x_cgo_getstackbound(uintptr bounds[2]) pthread_getattr_np(pthread_self(), &attr); // GNU extension pthread_attr_getstack(&attr, &addr, &size); // low address #elif defined(__illumos__) - pthread_attr_init(&attr); pthread_attr_get_np(pthread_self(), &attr); pthread_attr_getstack(&attr, &addr, &size); // low address #else - pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); addr = __builtin_frame_address(0) + 4096 - size; #endif pthread_attr_destroy(&attr); + // bounds points into the Go stack. TSAN can't see the synchronization + // in Go around stack reuse. + _cgo_tsan_acquire(); bounds[0] = (uintptr)addr; bounds[1] = (uintptr)addr + size; + _cgo_tsan_release(); } diff --git a/contrib/go/_std_1.22/src/runtime/cgocall.go b/contrib/go/_std_1.22/src/runtime/cgocall.go index f2dd98702d..0d3cc40903 100644 --- a/contrib/go/_std_1.22/src/runtime/cgocall.go +++ b/contrib/go/_std_1.22/src/runtime/cgocall.go @@ -214,15 +214,18 @@ func cgocall(fn, arg unsafe.Pointer) int32 { //go:nosplit func callbackUpdateSystemStack(mp *m, sp uintptr, signal bool) { g0 := mp.g0 - if sp > g0.stack.lo && sp <= g0.stack.hi { - // Stack already in bounds, nothing to do. - return - } - if mp.ncgo > 0 { + inBound := sp > g0.stack.lo && sp <= g0.stack.hi + if mp.ncgo > 0 && !inBound { // ncgo > 0 indicates that this M was in Go further up the stack - // (it called C and is now receiving a callback). It is not - // safe for the C call to change the stack out from under us. + // (it called C and is now receiving a callback). + // + // !inBound indicates that we were called with SP outside the + // expected system stack bounds (C changed the stack out from + // under us between the cgocall and cgocallback?). + // + // It is not safe for the C call to change the stack out from + // under us, so throw. // Note that this case isn't possible for signal == true, as // that is always passing a new M from needm. @@ -240,12 +243,26 @@ func callbackUpdateSystemStack(mp *m, sp uintptr, signal bool) { exit(2) } + if !mp.isextra { + // We allocated the stack for standard Ms. Don't replace the + // stack bounds with estimated ones when we already initialized + // with the exact ones. + return + } + // This M does not have Go further up the stack. However, it may have // previously called into Go, initializing the stack bounds. Between // that call returning and now the stack may have changed (perhaps the // C thread is running a coroutine library). We need to update the // stack bounds for this case. // + // N.B. we need to update the stack bounds even if SP appears to + // already be in bounds. Our "bounds" may actually be estimated dummy + // bounds (below). The actual stack bounds could have shifted but still + // have partial overlap with our dummy bounds. If we failed to update + // in that case, we could find ourselves seemingly called near the + // bottom of the stack bounds, where we quickly run out of space. + // Set the stack bounds to match the current stack. If we don't // actually know how big the stack is, like we don't know how big any // scheduling stack is, but we assume there's at least 32 kB. If we diff --git a/contrib/go/_std_1.22/src/runtime/internal/syscall/ya.make b/contrib/go/_std_1.22/src/runtime/internal/syscall/ya.make index 398b022c86..87ade4449e 100644 --- a/contrib/go/_std_1.22/src/runtime/internal/syscall/ya.make +++ b/contrib/go/_std_1.22/src/runtime/internal/syscall/ya.make @@ -1,17 +1,15 @@ -IF (OS_LINUX AND ARCH_AARCH64 AND RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND NOT CGO_ENABLED) GO_LIBRARY() +IF (OS_LINUX AND ARCH_AARCH64 AND RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND NOT CGO_ENABLED) SRCS( asm_linux_arm64.s defs_linux_arm64.go syscall_linux.go ) -END() ELSEIF (OS_LINUX AND ARCH_X86_64 AND RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND NOT RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND NOT RACE AND NOT CGO_ENABLED) -GO_LIBRARY() SRCS( asm_linux_amd64.s defs_linux_amd64.go syscall_linux.go ) -END() ENDIF() +END() diff --git a/contrib/go/_std_1.22/src/runtime/mgcsweep.go b/contrib/go/_std_1.22/src/runtime/mgcsweep.go index 3dbe9bcec7..35be794947 100644 --- a/contrib/go/_std_1.22/src/runtime/mgcsweep.go +++ b/contrib/go/_std_1.22/src/runtime/mgcsweep.go @@ -770,6 +770,19 @@ func (sl *sweepLocked) sweep(preserve bool) bool { if nfreed != 0 { // Free large object span to heap. + // Count the free in the consistent, external stats. + // + // Do this before freeSpan, which might update heapStats' inHeap + // value. If it does so, then metrics that subtract object footprint + // from inHeap might overflow. See #67019. + stats := memstats.heapStats.acquire() + atomic.Xadd64(&stats.largeFreeCount, 1) + atomic.Xadd64(&stats.largeFree, int64(size)) + memstats.heapStats.release() + + // Count the free in the inconsistent, internal stats. + gcController.totalFree.Add(int64(size)) + // NOTE(rsc,dvyukov): The original implementation of efence // in CL 22060046 used sysFree instead of sysFault, so that // the operating system would eventually give the memory @@ -802,16 +815,6 @@ func (sl *sweepLocked) sweep(preserve bool) bool { // invalid pointer. See arena.go:(*mheap).allocUserArenaChunk. *(*uintptr)(unsafe.Pointer(&s.largeType)) = 0 } - - // Count the free in the consistent, external stats. - stats := memstats.heapStats.acquire() - atomic.Xadd64(&stats.largeFreeCount, 1) - atomic.Xadd64(&stats.largeFree, int64(size)) - memstats.heapStats.release() - - // Count the free in the inconsistent, internal stats. - gcController.totalFree.Add(int64(size)) - return true } |