Update to go1.24.4
This commit is contained in:
4
VERSION
4
VERSION
@@ -1,2 +1,2 @@
|
||||
go1.24.3
|
||||
time 2025-04-30T18:13:34Z
|
||||
go1.24.4
|
||||
time 2025-05-29T19:37:36Z
|
||||
|
||||
1
lib/fips140/inprocess.txt
Normal file
1
lib/fips140/inprocess.txt
Normal file
@@ -0,0 +1 @@
|
||||
v1.0.0
|
||||
@@ -452,33 +452,50 @@ func (st *loadState) addSym(name string, ver int, r *oReader, li uint32, kind in
|
||||
if oldsym.Dupok() {
|
||||
return oldi
|
||||
}
|
||||
// If one is a DATA symbol (i.e. has content, DataSize != 0)
|
||||
// and the other is BSS, the one with content wins.
|
||||
// If one is a DATA symbol (i.e. has content, DataSize != 0,
|
||||
// including RODATA) and the other is BSS, the one with content wins.
|
||||
// If both are BSS, the one with larger size wins.
|
||||
// Specifically, the "overwrite" variable and the final result are
|
||||
//
|
||||
// new sym old sym overwrite
|
||||
// For a special case, we allow a TEXT symbol overwrites a BSS symbol
|
||||
// even if the BSS symbol has larger size. This is because there is
|
||||
// code like below to take the address of a function
|
||||
//
|
||||
// //go:linkname fn
|
||||
// var fn uintptr
|
||||
// var fnAddr = uintptr(unsafe.Pointer(&fn))
|
||||
//
|
||||
// TODO: maybe limit this case to just pointer sized variable?
|
||||
//
|
||||
// In summary, the "overwrite" variable and the final result are
|
||||
//
|
||||
// new sym old sym result
|
||||
// ---------------------------------------------
|
||||
// DATA DATA true => ERROR
|
||||
// DATA lg/eq BSS sm/eq true => new wins
|
||||
// DATA small BSS large true => ERROR
|
||||
// BSS large DATA small true => ERROR
|
||||
// BSS large BSS small true => new wins
|
||||
// BSS sm/eq D/B lg/eq false => old wins
|
||||
overwrite := r.DataSize(li) != 0 || oldsz < sz
|
||||
if overwrite {
|
||||
// TEXT BSS new wins
|
||||
// DATA DATA ERROR
|
||||
// DATA lg/eq BSS sm/eq new wins
|
||||
// DATA small BSS large ERROR
|
||||
// BSS large DATA small ERROR
|
||||
// BSS large BSS small new wins
|
||||
// BSS sm/eq D/B lg/eq old wins
|
||||
// BSS TEXT old wins
|
||||
oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
|
||||
newtyp := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
|
||||
oldIsText := oldtyp.IsText()
|
||||
newIsText := newtyp.IsText()
|
||||
oldHasContent := oldr.DataSize(oldli) != 0
|
||||
newHasContent := r.DataSize(li) != 0
|
||||
oldIsBSS := oldtyp.IsData() && !oldHasContent
|
||||
newIsBSS := newtyp.IsData() && !newHasContent
|
||||
switch {
|
||||
case newIsText && oldIsBSS,
|
||||
newHasContent && oldIsBSS && sz >= oldsz,
|
||||
newIsBSS && oldIsBSS && sz > oldsz:
|
||||
// new symbol overwrites old symbol.
|
||||
oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
|
||||
if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) || oldsz > sz {
|
||||
log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
|
||||
}
|
||||
l.objSyms[oldi] = objSym{r.objidx, li}
|
||||
} else {
|
||||
// old symbol overwrites new symbol.
|
||||
typ := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
|
||||
if !typ.IsData() { // only allow overwriting data symbol
|
||||
log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
|
||||
}
|
||||
case newIsBSS && (oldsz >= sz || oldIsText):
|
||||
// old win, just ignore the new symbol.
|
||||
default:
|
||||
log.Fatalf("duplicated definition of symbol %s, from %s (type %s size %d) and %s (type %s size %d)", name, r.unit.Lib.Pkg, newtyp, sz, oldr.unit.Lib.Pkg, oldtyp, oldsz)
|
||||
}
|
||||
return oldi
|
||||
}
|
||||
|
||||
@@ -1512,6 +1512,9 @@ func TestCheckLinkname(t *testing.T) {
|
||||
{"ok.go", true},
|
||||
// push linkname is ok
|
||||
{"push.go", true},
|
||||
// using a linknamed variable to reference an assembly
|
||||
// function in the same package is ok
|
||||
{"textvar", true},
|
||||
// pull linkname of blocked symbol is not ok
|
||||
{"coro.go", false},
|
||||
{"coro_var.go", false},
|
||||
@@ -1529,7 +1532,7 @@ func TestCheckLinkname(t *testing.T) {
|
||||
test := test
|
||||
t.Run(test.src, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
src := filepath.Join("testdata", "linkname", test.src)
|
||||
src := "./testdata/linkname/" + test.src
|
||||
exe := filepath.Join(tmpdir, test.src+".exe")
|
||||
cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe, src)
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
6
src/cmd/link/testdata/linkname/textvar/asm.s
vendored
Normal file
6
src/cmd/link/testdata/linkname/textvar/asm.s
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
TEXT ·asmfunc(SB),0,$0-0
|
||||
RET
|
||||
17
src/cmd/link/testdata/linkname/textvar/main.go
vendored
Normal file
17
src/cmd/link/testdata/linkname/textvar/main.go
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
// Using a linknamed variable to reference an assembly
|
||||
// function in the same package is ok.
|
||||
|
||||
package main
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
func main() {
|
||||
println(&asmfunc)
|
||||
}
|
||||
|
||||
//go:linkname asmfunc
|
||||
var asmfunc uintptr
|
||||
@@ -841,31 +841,45 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts.KeyUsages) == 0 {
|
||||
opts.KeyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
|
||||
}
|
||||
|
||||
for _, eku := range opts.KeyUsages {
|
||||
if eku == ExtKeyUsageAny {
|
||||
// If any key usage is acceptable, no need to check the chain for
|
||||
// key usages.
|
||||
return candidateChains, nil
|
||||
}
|
||||
}
|
||||
|
||||
chains = make([][]*Certificate, 0, len(candidateChains))
|
||||
var incompatibleKeyUsageChains, invalidPoliciesChains int
|
||||
|
||||
var invalidPoliciesChains int
|
||||
for _, candidate := range candidateChains {
|
||||
if !checkChainForKeyUsage(candidate, opts.KeyUsages) {
|
||||
incompatibleKeyUsageChains++
|
||||
continue
|
||||
}
|
||||
if !policiesValid(candidate, opts) {
|
||||
invalidPoliciesChains++
|
||||
continue
|
||||
}
|
||||
chains = append(chains, candidate)
|
||||
}
|
||||
|
||||
if len(chains) == 0 {
|
||||
return nil, CertificateInvalidError{c, NoValidChains, "all candidate chains have invalid policies"}
|
||||
}
|
||||
|
||||
for _, eku := range opts.KeyUsages {
|
||||
if eku == ExtKeyUsageAny {
|
||||
// If any key usage is acceptable, no need to check the chain for
|
||||
// key usages.
|
||||
return chains, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts.KeyUsages) == 0 {
|
||||
opts.KeyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
|
||||
}
|
||||
|
||||
candidateChains = chains
|
||||
chains = chains[:0]
|
||||
|
||||
var incompatibleKeyUsageChains int
|
||||
for _, candidate := range candidateChains {
|
||||
if !checkChainForKeyUsage(candidate, opts.KeyUsages) {
|
||||
incompatibleKeyUsageChains++
|
||||
continue
|
||||
}
|
||||
chains = append(chains, candidate)
|
||||
}
|
||||
|
||||
if len(chains) == 0 {
|
||||
var details []string
|
||||
if incompatibleKeyUsageChains > 0 {
|
||||
|
||||
@@ -3012,3 +3012,39 @@ func TestPoliciesValid(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPolicyWithAnyKeyUsage(t *testing.T) {
|
||||
loadTestCert := func(t *testing.T, path string) *Certificate {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p, _ := pem.Decode(b)
|
||||
c, err := ParseCertificate(p.Bytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
testOID3 := mustNewOIDFromInts([]uint64{1, 2, 840, 113554, 4, 1, 72585, 2, 3})
|
||||
root, intermediate, leaf := loadTestCert(t, "testdata/policy_root.pem"), loadTestCert(t, "testdata/policy_intermediate_require.pem"), loadTestCert(t, "testdata/policy_leaf.pem")
|
||||
|
||||
expectedErr := "x509: no valid chains built: all candidate chains have invalid policies"
|
||||
|
||||
roots, intermediates := NewCertPool(), NewCertPool()
|
||||
roots.AddCert(root)
|
||||
intermediates.AddCert(intermediate)
|
||||
|
||||
_, err := leaf.Verify(VerifyOptions{
|
||||
Roots: roots,
|
||||
Intermediates: intermediates,
|
||||
KeyUsages: []ExtKeyUsage{ExtKeyUsageAny},
|
||||
CertificatePolicies: []OID{testOID3},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("unexpected success, invalid policy shouldn't be bypassed by passing VerifyOptions.KeyUsages with ExtKeyUsageAny")
|
||||
} else if err.Error() != expectedErr {
|
||||
t.Fatalf("unexpected error, got %q, want %q", err, expectedErr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ func appendT(h *Hash, v reflect.Value) {
|
||||
case reflect.Bool:
|
||||
h.WriteByte(btoi(v.Bool()))
|
||||
return
|
||||
case reflect.UnsafePointer, reflect.Pointer:
|
||||
case reflect.UnsafePointer, reflect.Pointer, reflect.Chan:
|
||||
var buf [8]byte
|
||||
// because pointing to the abi.Escape call in comparableReady,
|
||||
// So this is ok to hash pointer,
|
||||
|
||||
@@ -253,12 +253,17 @@ func TestComparable(t *testing.T) {
|
||||
}
|
||||
testComparable(t, s1, s2)
|
||||
testComparable(t, s1.s, s2.s)
|
||||
c1 := make(chan struct{})
|
||||
c2 := make(chan struct{})
|
||||
testComparable(t, c1, c1)
|
||||
testComparable(t, chan struct{}(nil))
|
||||
testComparable(t, float32(0), negativeZero[float32]())
|
||||
testComparable(t, float64(0), negativeZero[float64]())
|
||||
testComparableNoEqual(t, math.NaN(), math.NaN())
|
||||
testComparableNoEqual(t, [2]string{"a", ""}, [2]string{"", "a"})
|
||||
testComparableNoEqual(t, struct{ a, b string }{"foo", ""}, struct{ a, b string }{"", "foo"})
|
||||
testComparableNoEqual(t, struct{ a, b any }{int(0), struct{}{}}, struct{ a, b any }{struct{}{}, int(0)})
|
||||
testComparableNoEqual(t, c1, c2)
|
||||
}
|
||||
|
||||
func testComparableNoEqual[T comparable](t *testing.T, v1, v2 T) {
|
||||
|
||||
@@ -88,6 +88,7 @@ func Openat(dirfd syscall.Handle, name string, flag int, perm uint32) (_ syscall
|
||||
switch {
|
||||
case flag&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
|
||||
disposition = FILE_CREATE
|
||||
options |= FILE_OPEN_REPARSE_POINT // don't follow symlinks
|
||||
case flag&syscall.O_CREAT == syscall.O_CREAT:
|
||||
disposition = FILE_OPEN_IF
|
||||
default:
|
||||
|
||||
@@ -805,7 +805,8 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(req *Request, stripSensit
|
||||
for k, vv := range ireqhdr {
|
||||
sensitive := false
|
||||
switch CanonicalHeaderKey(k) {
|
||||
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
|
||||
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2",
|
||||
"Proxy-Authorization", "Proxy-Authenticate":
|
||||
sensitive = true
|
||||
}
|
||||
if !(sensitive && stripSensitiveHeaders) {
|
||||
|
||||
@@ -1547,6 +1547,8 @@ func testClientStripHeadersOnRepeatedRedirect(t *testing.T, mode testMode) {
|
||||
if r.Host+r.URL.Path != "a.example.com/" {
|
||||
if h := r.Header.Get("Authorization"); h != "" {
|
||||
t.Errorf("on request to %v%v, Authorization=%q, want no header", r.Host, r.URL.Path, h)
|
||||
} else if h := r.Header.Get("Proxy-Authorization"); h != "" {
|
||||
t.Errorf("on request to %v%v, Proxy-Authorization=%q, want no header", r.Host, r.URL.Path, h)
|
||||
}
|
||||
}
|
||||
// Follow a chain of redirects from a to b and back to a.
|
||||
@@ -1575,6 +1577,7 @@ func testClientStripHeadersOnRepeatedRedirect(t *testing.T, mode testMode) {
|
||||
req, _ := NewRequest("GET", proto+"://a.example.com/", nil)
|
||||
req.Header.Add("Cookie", "foo=bar")
|
||||
req.Header.Add("Authorization", "secretpassword")
|
||||
req.Header.Add("Proxy-Authorization", "secretpassword")
|
||||
res, err := c.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -2223,6 +2223,31 @@ func TestFilePermissions(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestOpenFileCreateExclDanglingSymlink(t *testing.T) {
|
||||
testMaybeRooted(t, func(t *testing.T, r *Root) {
|
||||
const link = "link"
|
||||
if err := Symlink("does_not_exist", link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var f *File
|
||||
var err error
|
||||
if r == nil {
|
||||
f, err = OpenFile(link, O_WRONLY|O_CREATE|O_EXCL, 0o444)
|
||||
} else {
|
||||
f, err = r.OpenFile(link, O_WRONLY|O_CREATE|O_EXCL, 0o444)
|
||||
}
|
||||
if err == nil {
|
||||
f.Close()
|
||||
}
|
||||
if !errors.Is(err, ErrExist) {
|
||||
t.Errorf("OpenFile of a dangling symlink with O_CREATE|O_EXCL = %v, want ErrExist", err)
|
||||
}
|
||||
if _, err := Stat(link); err == nil {
|
||||
t.Errorf("OpenFile of a dangling symlink with O_CREATE|O_EXCL created a file")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestFileRDWRFlags tests the O_RDONLY, O_WRONLY, and O_RDWR flags.
|
||||
func TestFileRDWRFlags(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
|
||||
@@ -77,6 +77,7 @@ type Module struct {
|
||||
// - CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable
|
||||
// - CGO_CXXFLAGS: the effective CGO_CXXFLAGS environment variable
|
||||
// - CGO_LDFLAGS: the effective CGO_LDFLAGS environment variable
|
||||
// - DefaultGODEBUG: the effective GODEBUG settings
|
||||
// - GOARCH: the architecture target
|
||||
// - GOAMD64/GOARM/GO386/etc: the architecture feature level for GOARCH
|
||||
// - GOOS: the operating system target
|
||||
|
||||
@@ -376,20 +376,6 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
|
||||
if flag&O_CLOEXEC == 0 {
|
||||
sa = makeInheritSa()
|
||||
}
|
||||
// We don't use CREATE_ALWAYS, because when opening a file with
|
||||
// FILE_ATTRIBUTE_READONLY these will replace an existing file
|
||||
// with a new, read-only one. See https://go.dev/issue/38225.
|
||||
//
|
||||
// Instead, we ftruncate the file after opening when O_TRUNC is set.
|
||||
var createmode uint32
|
||||
switch {
|
||||
case flag&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
|
||||
createmode = CREATE_NEW
|
||||
case flag&O_CREAT == O_CREAT:
|
||||
createmode = OPEN_ALWAYS
|
||||
default:
|
||||
createmode = OPEN_EXISTING
|
||||
}
|
||||
var attrs uint32 = FILE_ATTRIBUTE_NORMAL
|
||||
if perm&S_IWRITE == 0 {
|
||||
attrs = FILE_ATTRIBUTE_READONLY
|
||||
@@ -404,6 +390,21 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
|
||||
const _FILE_FLAG_WRITE_THROUGH = 0x80000000
|
||||
attrs |= _FILE_FLAG_WRITE_THROUGH
|
||||
}
|
||||
// We don't use CREATE_ALWAYS, because when opening a file with
|
||||
// FILE_ATTRIBUTE_READONLY these will replace an existing file
|
||||
// with a new, read-only one. See https://go.dev/issue/38225.
|
||||
//
|
||||
// Instead, we ftruncate the file after opening when O_TRUNC is set.
|
||||
var createmode uint32
|
||||
switch {
|
||||
case flag&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
|
||||
createmode = CREATE_NEW
|
||||
attrs |= FILE_FLAG_OPEN_REPARSE_POINT // don't follow symlinks
|
||||
case flag&O_CREAT == O_CREAT:
|
||||
createmode = OPEN_ALWAYS
|
||||
default:
|
||||
createmode = OPEN_EXISTING
|
||||
}
|
||||
h, err := createFile(namep, access, sharemode, sa, createmode, attrs, 0)
|
||||
if h == InvalidHandle {
|
||||
if err == ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
|
||||
|
||||
Reference in New Issue
Block a user