[dev.boringcrypto.go1.18] all: merge go1.18.9 into dev.boringcrypto.go1.18

Change-Id: I5eda3a3fb2fc381e237d18d2846cf1b1810d8015
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index 997a830..dc56398 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -2215,6 +2215,8 @@
 	"long long unsigned int": "ulonglong",
 	"signed char":            "schar",
 	"unsigned char":          "uchar",
+	"unsigned long":          "ulong",     // Used by Clang 14; issue 53013.
+	"unsigned long long":     "ulonglong", // Used by Clang 14; issue 53013.
 }
 
 const signedDelta = 64
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index b36db67..17ec877 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -323,7 +323,9 @@
 		}
 		n := ir.AsNode(typecheck.Lookup(l.local).Def)
 		if n == nil || n.Op() != ir.ONAME {
-			p.errorAt(l.pos, "//go:linkname must refer to declared function or variable")
+			if types.AllowsGoVersion(types.LocalPkg, 1, 18) {
+				p.errorAt(l.pos, "//go:linkname must refer to declared function or variable")
+			}
 			continue
 		}
 		if n.Sym().Linkname != "" {
diff --git a/src/cmd/compile/internal/test/race.go b/src/cmd/compile/internal/test/race.go
new file mode 100644
index 0000000..4cc4d53
--- /dev/null
+++ b/src/cmd/compile/internal/test/race.go
@@ -0,0 +1,65 @@
+// 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 !compiler_bootstrap
+// +build !compiler_bootstrap
+
+package test
+
+// The racecompile builder only builds packages, but does not build
+// or run tests. This is a non-test file to hold cases that (used
+// to) trigger compiler data races, so they will be exercised on
+// the racecompile builder.
+//
+// This package is not imported so functions here are not included
+// in the actual compiler.
+
+// Issue 55357: data race when building multiple instantiations of
+// generic closures with _ parameters.
+func Issue55357() {
+	type U struct {
+		A int
+		B string
+		C string
+	}
+	var q T55357[U]
+	q.Count()
+	q.List()
+
+	type M struct {
+		A int64
+		B uint32
+		C uint32
+	}
+	var q2 T55357[M]
+	q2.Count()
+	q2.List()
+}
+
+type T55357[T any] struct{}
+
+//go:noinline
+func (q *T55357[T]) do(w, v bool, fn func(bk []byte, v T) error) error {
+	return nil
+}
+
+func (q *T55357[T]) Count() (n int, rerr error) {
+	err := q.do(false, false, func(kb []byte, _ T) error {
+		n++
+		return nil
+	})
+	return n, err
+}
+
+func (q *T55357[T]) List() (list []T, rerr error) {
+	var l []T
+	err := q.do(false, true, func(_ []byte, v T) error {
+		l = append(l, v)
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+	return l, nil
+}
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index a41a3d6..7c48fb5 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -1356,7 +1356,8 @@
 				newfields[i].SetNointerface(true)
 			}
 			if f.Nname != nil && ts.Vars != nil {
-				v := ts.Vars[f.Nname.(*ir.Name)]
+				n := f.Nname.(*ir.Name)
+				v := ts.Vars[n]
 				if v != nil {
 					// This is the case where we are
 					// translating the type of the function we
@@ -1364,6 +1365,13 @@
 					// the subst.ts.vars table, and we want to
 					// change to reference the new dcl.
 					newfields[i].Nname = v
+				} else if ir.IsBlank(n) {
+					// Blank variable is not dcl list. Make a
+					// new one to not share.
+					m := ir.NewNameAt(n.Pos(), ir.BlankNode.Sym())
+					m.SetType(n.Type())
+					m.SetTypecheck(1)
+					newfields[i].Nname = m
 				} else {
 					// This is the case where we are
 					// translating the type of a function
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
index 56c3b25..cd4d523 100644
--- a/src/cmd/internal/moddeps/moddeps_test.go
+++ b/src/cmd/internal/moddeps/moddeps_test.go
@@ -34,6 +34,8 @@
 // See issues 36852, 41409, and 43687.
 // (Also see golang.org/issue/27348.)
 func TestAllDependencies(t *testing.T) {
+	t.Skip("TODO(#57008): 1.18.9 contains unreleased changes from vendored modules")
+
 	goBin := testenv.GoToolPath(t)
 
 	// Ensure that all packages imported within GOROOT
diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
index 100a8ff..c3ef503 100644
--- a/src/crypto/x509/verify_test.go
+++ b/src/crypto/x509/verify_test.go
@@ -540,8 +540,8 @@
 func TestGoVerify(t *testing.T) {
 	// Temporarily enable SHA-1 verification since a number of test chains
 	// require it. TODO(filippo): regenerate test chains.
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = true
+	t.Setenv("GODEBUG", "x509sha1=1")
+
 	for _, test := range verifyTests {
 		t.Run(test.name, func(t *testing.T) {
 			testVerify(t, test, false)
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 85720b3..dc470f5 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -730,9 +730,6 @@
 // involves algorithms that are not currently implemented.
 var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
 
-// debugAllowSHA1 allows SHA-1 signatures. See issue 41682.
-var debugAllowSHA1 = godebug.Get("x509sha1") == "1"
-
 // An InsecureAlgorithmError indicates that the SignatureAlgorithm used to
 // generate the signature is not secure, and the signature has been rejected.
 //
@@ -792,7 +789,7 @@
 
 	// TODO(agl): don't ignore the path length constraint.
 
-	return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, debugAllowSHA1)
+	return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
 }
 
 // CheckSignature verifies that signature is a valid signature over signed from
@@ -839,7 +836,8 @@
 	case crypto.MD5:
 		return InsecureAlgorithmError(algo)
 	case crypto.SHA1:
-		if !allowSHA1 {
+		// SHA-1 signatures are mostly disabled. See go.dev/issue/41682.
+		if !allowSHA1 && godebug.Get("x509sha1") != "1" {
 			return InsecureAlgorithmError(algo)
 		}
 		fallthrough
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 6c1e95a..48a8640 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -1864,9 +1864,7 @@
 		t.Fatalf("certificate verification returned %v (%T), wanted InsecureAlgorithmError", err, err)
 	}
 
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = true
-
+	t.Setenv("GODEBUG", "x509sha1=1")
 	if err = cert.CheckSignatureFrom(cert); err != nil {
 		t.Fatalf("SHA-1 certificate did not verify with GODEBUG=x509sha1=1: %v", err)
 	}
@@ -3335,8 +3333,7 @@
 }
 
 func TestDisableSHA1ForCertOnly(t *testing.T) {
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = false
+	t.Setenv("GODEBUG", "")
 
 	tmpl := &Certificate{
 		SerialNumber:          big.NewInt(1),
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index ed8ddcb..2a21800 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -168,6 +168,7 @@
 	io/fs
 	< internal/testlog
 	< internal/poll
+	< internal/safefilepath
 	< os
 	< os/signal;
 
diff --git a/src/internal/safefilepath/path.go b/src/internal/safefilepath/path.go
new file mode 100644
index 0000000..0f0a270
--- /dev/null
+++ b/src/internal/safefilepath/path.go
@@ -0,0 +1,21 @@
+// 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.
+
+// Package safefilepath manipulates operating-system file paths.
+package safefilepath
+
+import (
+	"errors"
+)
+
+var errInvalidPath = errors.New("invalid path")
+
+// FromFS converts a slash-separated path into an operating-system path.
+//
+// FromFS returns an error if the path cannot be represented by the operating
+// system. For example, paths containing '\' and ':' characters are rejected
+// on Windows.
+func FromFS(path string) (string, error) {
+	return fromFS(path)
+}
diff --git a/src/internal/safefilepath/path_other.go b/src/internal/safefilepath/path_other.go
new file mode 100644
index 0000000..f93da18
--- /dev/null
+++ b/src/internal/safefilepath/path_other.go
@@ -0,0 +1,23 @@
+// 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 !windows
+
+package safefilepath
+
+import "runtime"
+
+func fromFS(path string) (string, error) {
+	if runtime.GOOS == "plan9" {
+		if len(path) > 0 && path[0] == '#' {
+			return path, errInvalidPath
+		}
+	}
+	for i := range path {
+		if path[i] == 0 {
+			return "", errInvalidPath
+		}
+	}
+	return path, nil
+}
diff --git a/src/internal/safefilepath/path_test.go b/src/internal/safefilepath/path_test.go
new file mode 100644
index 0000000..dc662c1
--- /dev/null
+++ b/src/internal/safefilepath/path_test.go
@@ -0,0 +1,88 @@
+// 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.
+
+package safefilepath_test
+
+import (
+	"internal/safefilepath"
+	"os"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+type PathTest struct {
+	path, result string
+}
+
+const invalid = ""
+
+var fspathtests = []PathTest{
+	{".", "."},
+	{"/a/b/c", "/a/b/c"},
+	{"a\x00b", invalid},
+}
+
+var winreservedpathtests = []PathTest{
+	{`a\b`, `a\b`},
+	{`a:b`, `a:b`},
+	{`a/b:c`, `a/b:c`},
+	{`NUL`, `NUL`},
+	{`./com1`, `./com1`},
+	{`a/nul/b`, `a/nul/b`},
+}
+
+// Whether a reserved name with an extension is reserved or not varies by
+// Windows version.
+var winreservedextpathtests = []PathTest{
+	{"nul.txt", "nul.txt"},
+	{"a/nul.txt/b", "a/nul.txt/b"},
+}
+
+var plan9reservedpathtests = []PathTest{
+	{`#c`, `#c`},
+}
+
+func TestFromFS(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows":
+		if canWriteFile(t, "NUL") {
+			t.Errorf("can unexpectedly write a file named NUL on Windows")
+		}
+		if canWriteFile(t, "nul.txt") {
+			fspathtests = append(fspathtests, winreservedextpathtests...)
+		} else {
+			winreservedpathtests = append(winreservedpathtests, winreservedextpathtests...)
+		}
+		for i := range winreservedpathtests {
+			winreservedpathtests[i].result = invalid
+		}
+		for i := range fspathtests {
+			fspathtests[i].result = filepath.FromSlash(fspathtests[i].result)
+		}
+	case "plan9":
+		for i := range plan9reservedpathtests {
+			plan9reservedpathtests[i].result = invalid
+		}
+	}
+	tests := fspathtests
+	tests = append(tests, winreservedpathtests...)
+	tests = append(tests, plan9reservedpathtests...)
+	for _, test := range tests {
+		got, err := safefilepath.FromFS(test.path)
+		if (got == "") != (err != nil) {
+			t.Errorf(`FromFS(%q) = %q, %v; want "" only if err != nil`, test.path, got, err)
+		}
+		if got != test.result {
+			t.Errorf("FromFS(%q) = %q, %v; want %q", test.path, got, err, test.result)
+		}
+	}
+}
+
+func canWriteFile(t *testing.T, name string) bool {
+	path := filepath.Join(t.TempDir(), name)
+	os.WriteFile(path, []byte("ok"), 0666)
+	b, _ := os.ReadFile(path)
+	return string(b) == "ok"
+}
diff --git a/src/internal/safefilepath/path_windows.go b/src/internal/safefilepath/path_windows.go
new file mode 100644
index 0000000..909c150
--- /dev/null
+++ b/src/internal/safefilepath/path_windows.go
@@ -0,0 +1,95 @@
+// 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.
+
+package safefilepath
+
+import (
+	"syscall"
+	"unicode/utf8"
+)
+
+func fromFS(path string) (string, error) {
+	if !utf8.ValidString(path) {
+		return "", errInvalidPath
+	}
+	for len(path) > 1 && path[0] == '/' && path[1] == '/' {
+		path = path[1:]
+	}
+	containsSlash := false
+	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++
+		}
+		part := p[:i]
+		if i < len(p) {
+			containsSlash = true
+			p = p[i+1:]
+		} 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 containsSlash {
+		// We can't depend on strings, so substitute \ for / manually.
+		buf := []byte(path)
+		for i, b := range buf {
+			if b == '/' {
+				buf[i] = '\\'
+			}
+		}
+		path = string(buf)
+	}
+	return path, nil
+}
+
+// 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 {
+		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'
+		}
+	}
+	return false
+}
+
+func toUpper(c byte) byte {
+	if 'a' <= c && c <= 'z' {
+		return c - ('a' - 'A')
+	}
+	return c
+}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 6caee9e..5832030 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -9,6 +9,7 @@
 import (
 	"errors"
 	"fmt"
+	"internal/safefilepath"
 	"io"
 	"io/fs"
 	"mime"
@@ -69,14 +70,15 @@
 // Open implements FileSystem using os.Open, opening files for reading rooted
 // and relative to the directory d.
 func (d Dir) Open(name string) (File, error) {
-	if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
-		return nil, errors.New("http: invalid character in file path")
+	path, err := safefilepath.FromFS(path.Clean("/" + name))
+	if err != nil {
+		return nil, errors.New("http: invalid or unsafe file path")
 	}
 	dir := string(d)
 	if dir == "" {
 		dir = "."
 	}
-	fullName := filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))
+	fullName := filepath.Join(dir, path)
 	f, err := os.Open(fullName)
 	if err != nil {
 		return nil, mapOpenError(err, fullName, filepath.Separator, os.Stat)
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index d627dfd..323360d 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -648,6 +648,34 @@
 	}
 }
 
+func TestFileServerNamesEscape(t *testing.T) {
+	t.Run("h1", func(t *testing.T) {
+		testFileServerNamesEscape(t, h1Mode)
+	})
+	t.Run("h2", func(t *testing.T) {
+		testFileServerNamesEscape(t, h2Mode)
+	})
+}
+func testFileServerNamesEscape(t *testing.T, h2 bool) {
+	defer afterTest(t)
+	ts := newClientServerTest(t, h2, FileServer(Dir("testdata"))).ts
+	defer ts.Close()
+	for _, path := range []string{
+		"/../testdata/file",
+		"/NUL", // don't read from device files on Windows
+	} {
+		res, err := ts.Client().Get(ts.URL + path)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res.Body.Close()
+		if res.StatusCode < 400 || res.StatusCode > 599 {
+			t.Errorf("Get(%q): got status %v, want 4xx or 5xx", path, res.StatusCode)
+		}
+
+	}
+}
+
 type fakeFileInfo struct {
 	dir      bool
 	basename string
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 292dded..381f91c 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -3384,10 +3384,11 @@
 // name (key). See httpguts.ValidHeaderName for the base rules.
 //
 // Further, http2 says:
-//   "Just as in HTTP/1.x, header field names are strings of ASCII
-//   characters that are compared in a case-insensitive
-//   fashion. However, header field names MUST be converted to
-//   lowercase prior to their encoding in HTTP/2. "
+//
+//	"Just as in HTTP/1.x, header field names are strings of ASCII
+//	characters that are compared in a case-insensitive
+//	fashion. However, header field names MUST be converted to
+//	lowercase prior to their encoding in HTTP/2. "
 func http2validWireHeaderFieldName(v string) bool {
 	if len(v) == 0 {
 		return false
@@ -3578,8 +3579,8 @@
 // validPseudoPath reports whether v is a valid :path pseudo-header
 // value. It must be either:
 //
-//     *) a non-empty string starting with '/'
-//     *) the string '*', for OPTIONS requests.
+//	*) a non-empty string starting with '/'
+//	*) the string '*', for OPTIONS requests.
 //
 // For now this is only used a quick check for deciding when to clean
 // up Opaque URLs before sending requests from the Transport.
@@ -4242,6 +4243,7 @@
 	headerTableSize             uint32
 	peerMaxHeaderListSize       uint32            // zero means unknown (default)
 	canonHeader                 map[string]string // http2-lower-case -> Go-Canonical-Case
+	canonHeaderKeysSize         int               // canonHeader keys size in bytes
 	writingFrame                bool              // started writing a frame (on serve goroutine or separate)
 	writingFrameAsync           bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh
 	needsFrameFlush             bool              // last frame write wasn't a flush
@@ -4421,6 +4423,13 @@
 	}
 }
 
+// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
+// of the entries in the canonHeader cache.
+// This should be larger than the size of unique, uncommon header keys likely to
+// be sent by the peer, while not so high as to permit unreasonable memory usage
+// if the peer sends an unbounded number of unique header keys.
+const http2maxCachedCanonicalHeadersKeysSize = 2048
+
 func (sc *http2serverConn) canonicalHeader(v string) string {
 	sc.serveG.check()
 	http2buildCommonHeaderMapsOnce()
@@ -4436,14 +4445,10 @@
 		sc.canonHeader = make(map[string]string)
 	}
 	cv = CanonicalHeaderKey(v)
-	// maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
-	// entries in the canonHeader cache. This should be larger than the number
-	// of unique, uncommon header keys likely to be sent by the peer, while not
-	// so high as to permit unreaasonable memory usage if the peer sends an unbounded
-	// number of unique header keys.
-	const maxCachedCanonicalHeaders = 32
-	if len(sc.canonHeader) < maxCachedCanonicalHeaders {
+	size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
+	if sc.canonHeaderKeysSize+size <= http2maxCachedCanonicalHeadersKeysSize {
 		sc.canonHeader[v] = cv
+		sc.canonHeaderKeysSize += size
 	}
 	return cv
 }
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index 3a31f56..655543c 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -71,6 +71,10 @@
 var backoffDuration = [...]time.Duration{time.Second, 5 * time.Second, 30 * time.Second}
 
 func TestLookupGoogleSRV(t *testing.T) {
+	// TODO(mknyszek): Figure out next steps for this test. This is just
+	// a quick fix.
+	t.Skip("fails consistently due to an upstream DNS change; see #56707.")
+
 	t.Parallel()
 	mustHaveExternalNetwork(t)
 
@@ -631,6 +635,10 @@
 }
 
 func TestLookupDotsWithRemoteSource(t *testing.T) {
+	// TODO(mknyszek): Figure out next steps for this test. This is just
+	// a quick fix.
+	t.Skip("fails consistently due to an upstream DNS change; see #56707.")
+
 	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
 		testenv.SkipFlaky(t, 27992)
 	}
diff --git a/src/os/exec/env_test.go b/src/os/exec/env_test.go
index 47b7c04..43d14fb 100644
--- a/src/os/exec/env_test.go
+++ b/src/os/exec/env_test.go
@@ -12,6 +12,7 @@
 func TestDedupEnv(t *testing.T) {
 	tests := []struct {
 		noCase  bool
+		nulOK   bool
 		in      []string
 		want    []string
 		wantErr bool
@@ -36,9 +37,15 @@
 			want:    []string{"B=b"},
 			wantErr: true,
 		},
+		{
+			// Plan 9 needs to preserve environment variables with NUL (#56544).
+			nulOK: true,
+			in:    []string{"path=one\x00two"},
+			want:  []string{"path=one\x00two"},
+		},
 	}
 	for _, tt := range tests {
-		got, err := dedupEnvCase(tt.noCase, tt.in)
+		got, err := dedupEnvCase(tt.noCase, tt.nulOK, tt.in)
 		if !reflect.DeepEqual(got, tt.want) || (err != nil) != tt.wantErr {
 			t.Errorf("Dedup(%v, %q) = %q, %v; want %q, error:%v", tt.noCase, tt.in, got, err, tt.want, tt.wantErr)
 		}
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
index 056a7e0..e1147b7 100644
--- a/src/os/exec/exec.go
+++ b/src/os/exec/exec.go
@@ -745,23 +745,27 @@
 // dedupEnv returns a copy of env with any duplicates removed, in favor of
 // later values.
 // Items not of the normal environment "key=value" form are preserved unchanged.
-// Items containing NUL characters are removed, and an error is returned along with
-// the remaining values.
+// Except on Plan 9, items containing NUL characters are removed, and
+// an error is returned along with the remaining values.
 func dedupEnv(env []string) ([]string, error) {
-	return dedupEnvCase(runtime.GOOS == "windows", env)
+	return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
 }
 
 // dedupEnvCase is dedupEnv with a case option for testing.
 // If caseInsensitive is true, the case of keys is ignored.
-func dedupEnvCase(caseInsensitive bool, env []string) ([]string, error) {
+// If nulOK is false, items containing NUL characters are allowed.
+func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
 	var err error
 	out := make([]string, 0, len(env))
 	saw := make(map[string]int, len(env)) // key => index into out
 	for _, kv := range env {
-		if strings.IndexByte(kv, 0) != -1 {
+		// Reject NUL in environment variables to prevent security issues (#56284);
+		// except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
+		if !nulOK && strings.IndexByte(kv, 0) != -1 {
 			err = errors.New("exec: environment variable contains NUL")
 			continue
 		}
+
 		k, _, ok := strings.Cut(kv, "=")
 		if !ok {
 			out = append(out, kv)
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 0be8c6c..99bc032 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -1030,6 +1030,9 @@
 }
 
 func TestEnvNULCharacter(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("plan9 explicitly allows NUL in the enviroment")
+	}
 	cmd := helperCommand(t, "echoenv", "FOO", "BAR")
 	cmd.Env = append(cmd.Env, "FOO=foo\x00BAR=bar")
 	out, err := cmd.CombinedOutput()
diff --git a/src/os/file.go b/src/os/file.go
index 2823128..8afc6e3 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -37,12 +37,12 @@
 // Note: The maximum number of concurrent operations on a File may be limited by
 // the OS or the system. The number should be high, but exceeding it may degrade
 // performance or cause other issues.
-//
 package os
 
 import (
 	"errors"
 	"internal/poll"
+	"internal/safefilepath"
 	"internal/testlog"
 	"internal/unsafeheader"
 	"io"
@@ -623,6 +623,8 @@
 // the /prefix tree, then using DirFS does not stop the access any more than using
 // os.Open does. DirFS is therefore not a general substitute for a chroot-style security
 // mechanism when the directory tree contains arbitrary content.
+//
+// The directory dir must not be "".
 func DirFS(dir string) fs.FS {
 	return dirFS(dir)
 }
@@ -641,10 +643,11 @@
 type dirFS string
 
 func (dir dirFS) Open(name string) (fs.File, error) {
-	if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
-		return nil, &PathError{Op: "open", Path: name, Err: ErrInvalid}
+	fullname, err := dir.join(name)
+	if err != nil {
+		return nil, &PathError{Op: "stat", Path: name, Err: err}
 	}
-	f, err := Open(string(dir) + "/" + name)
+	f, err := Open(fullname)
 	if err != nil {
 		return nil, err // nil fs.File
 	}
@@ -652,16 +655,35 @@
 }
 
 func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
-	if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
-		return nil, &PathError{Op: "stat", Path: name, Err: ErrInvalid}
+	fullname, err := dir.join(name)
+	if err != nil {
+		return nil, &PathError{Op: "stat", Path: name, Err: err}
 	}
-	f, err := Stat(string(dir) + "/" + name)
+	f, err := Stat(fullname)
 	if err != nil {
 		return nil, err
 	}
 	return f, nil
 }
 
+// join returns the path for name in dir.
+func (dir dirFS) join(name string) (string, error) {
+	if dir == "" {
+		return "", errors.New("os: DirFS with empty root")
+	}
+	if !fs.ValidPath(name) {
+		return "", ErrInvalid
+	}
+	name, err := safefilepath.FromFS(name)
+	if err != nil {
+		return "", ErrInvalid
+	}
+	if IsPathSeparator(dir[len(dir)-1]) {
+		return string(dir) + name, nil
+	}
+	return string(dir) + string(PathSeparator) + name, nil
+}
+
 // ReadFile reads the named file and returns the contents.
 // A successful call returns err == nil, not err == EOF.
 // Because ReadFile reads the whole file, it does not treat an EOF from Read
diff --git a/src/os/os_test.go b/src/os/os_test.go
index 63427de..4124be1 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -2696,6 +2696,44 @@
 	if err == nil {
 		t.Fatalf(`Open testdata\dirfs succeeded`)
 	}
+
+	// Test that Open does not open Windows device files.
+	_, err = d.Open(`NUL`)
+	if err == nil {
+		t.Errorf(`Open NUL succeeded`)
+	}
+}
+
+func TestDirFSRootDir(t *testing.T) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cwd = cwd[len(filepath.VolumeName(cwd)):] // trim volume prefix (C:) on Windows
+	cwd = filepath.ToSlash(cwd)               // convert \ to /
+	cwd = strings.TrimPrefix(cwd, "/")        // trim leading /
+
+	// Test that Open can open a path starting at /.
+	d := DirFS("/")
+	f, err := d.Open(cwd + "/testdata/dirfs/a")
+	if err != nil {
+		t.Fatal(err)
+	}
+	f.Close()
+}
+
+func TestDirFSEmptyDir(t *testing.T) {
+	d := DirFS("")
+	cwd, _ := os.Getwd()
+	for _, path := range []string{
+		"testdata/dirfs/a",                          // not DirFS(".")
+		filepath.ToSlash(cwd) + "/testdata/dirfs/a", // not DirFS("/")
+	} {
+		_, err := d.Open(path)
+		if err == nil {
+			t.Fatalf(`DirFS("").Open(%q) succeeded`, path)
+		}
+	}
 }
 
 func TestDirFSPathsValid(t *testing.T) {
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 6ed6cea..d738644 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -1135,6 +1135,16 @@
 	// the garbage collector could follow a pointer to x,
 	// but see uninitialized memory or stale heap bits.
 	publicationBarrier()
+	// As x and the heap bits are initialized, update
+	// freeIndexForScan now so x is seen by the GC
+	// (including convervative scan) as an allocated object.
+	// While this pointer can't escape into user code as a
+	// _live_ pointer until we return, conservative scanning
+	// may find a dead pointer that happens to point into this
+	// object. Delaying this update until now ensures that
+	// conservative scanning considers this pointer dead until
+	// this point.
+	span.freeIndexForScan = span.freeindex
 
 	// Allocate black during GC.
 	// All slots hold nil so no scanning is needed.
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index 9379688..95d88d8 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -220,7 +220,7 @@
 // been no preemption points since ensuring this (which could allow a
 // GC transition, which would allow the state to change).
 func (s *mspan) isFree(index uintptr) bool {
-	if index < s.freeindex {
+	if index < s.freeIndexForScan {
 		return false
 	}
 	bytep, mask := s.allocBits.bitp(index)
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index 0d58f8e..2aa670e 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -623,6 +623,7 @@
 
 	s.allocCount = nalloc
 	s.freeindex = 0 // reset allocation index to start of span.
+	s.freeIndexForScan = 0
 	if trace.enabled {
 		getg().m.p.ptr().traceReclaimed += uintptr(nfreed) * s.elemsize
 	}
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index ecbd0a3..1343875 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -459,6 +459,14 @@
 	limit       uintptr       // end of data in span
 	speciallock mutex         // guards specials list
 	specials    *special      // linked list of special records sorted by offset.
+
+	// freeIndexForScan is like freeindex, except that freeindex is
+	// used by the allocator whereas freeIndexForScan is used by the
+	// GC scanner. They are two fields so that the GC sees the object
+	// is allocated only when the object and the heap bits are
+	// initialized (see also the assignment of freeIndexForScan in
+	// mallocgc, and issue 54596).
+	freeIndexForScan uintptr
 }
 
 func (s *mspan) base() uintptr {
@@ -1250,6 +1258,7 @@
 
 		// Initialize mark and allocation structures.
 		s.freeindex = 0
+		s.freeIndexForScan = 0
 		s.allocCache = ^uint64(0) // all 1s indicating all free.
 		s.gcmarkBits = newMarkBits(s.nelems)
 		s.allocBits = newAllocBits(s.nelems)
@@ -1565,6 +1574,7 @@
 	span.specials = nil
 	span.needzero = 0
 	span.freeindex = 0
+	span.freeIndexForScan = 0
 	span.allocBits = nil
 	span.gcmarkBits = nil
 	span.state.set(mSpanDead)
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 01d6c85..b86a820 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -119,16 +119,23 @@
 	MOVW	R3, errno+16(FP)
 	RET
 
+// func usleep(usec uint32)
 TEXT runtime·usleep(SB),NOSPLIT,$16-4
 	MOVW	usec+0(FP), R3
-	MOVD	R3, R5
-	MOVW	$1000000, R4
-	DIVD	R4, R3
-	MOVD	R3, 8(R1)
-	MOVW	$1000, R4
-	MULLD	R3, R4
-	SUB	R4, R5
-	MOVD	R5, 16(R1)
+
+	// Use magic constant 0x8637bd06 and shift right 51
+	// to perform usec/1000000.
+	ORIS	$0x8637, R0, R4	// Note, R0 always contains 0 here.
+	OR	$0xbd06, R4, R4
+	MULLD	R3, R4, R4	// Convert usec to S.
+	SRD	$51, R4, R4
+	MOVD	R4, 8(R1)	// Store to tv_sec
+
+	MOVD	$1000000, R5
+	MULLW	R4, R5, R5	// Convert tv_sec back into uS
+	SUB	R5, R3, R5	// Compute remainder uS.
+	MULLD	$1000, R5, R5	// Convert to nsec
+	MOVD	R5, 16(R1)	// Store to tv_nsec
 
 	// nanosleep(&ts, 0)
 	ADD	$8, R1, R3
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 56128dc..b8f580f 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -182,6 +182,17 @@
 				case funcID_systemstack:
 					// systemstack returns normally, so just follow the
 					// stack transition.
+					if usesLR && funcspdelta(f, frame.pc, &cache) == 0 {
+						// We're at the function prologue and the stack
+						// switch hasn't happened, or epilogue where we're
+						// about to return. Just unwind normally.
+						// Do this only on LR machines because on x86
+						// systemstack doesn't have an SP delta (the CALL
+						// instruction opens the frame), therefore no way
+						// to check.
+						flag &^= funcFlag_SPWRITE
+						break
+					}
 					frame.sp = gp.m.curg.sched.sp
 					stack = gp.m.curg.stack
 					cgoCtxt = gp.m.curg.cgoCtxt
diff --git a/test/fixedbugs/issue55889.go b/test/fixedbugs/issue55889.go
new file mode 100644
index 0000000..68812c2
--- /dev/null
+++ b/test/fixedbugs/issue55889.go
@@ -0,0 +1,21 @@
+// errorcheck -0 -lang=go1.17
+
+// 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.
+
+// Prior to Go 1.18, ineffectual //go:linkname directives were treated
+// as noops. Ensure that modules that contain these directives (e.g.,
+// x/sys prior to go.dev/cl/274573) continue to compile.
+
+package p
+
+import _ "unsafe"
+
+//go:linkname nonexistent nonexistent
+
+//go:linkname constant constant
+const constant = 42
+
+//go:linkname typename typename
+type typename int