diff options
author | Heschi Kreinick <heschi@google.com> | 2021-10-07 19:02:56 -0400 |
---|---|---|
committer | Heschi Kreinick <heschi@google.com> | 2021-10-07 19:02:56 -0400 |
commit | 35d5cd0dcfb9d06064ec37da1621d24676454058 (patch) | |
tree | 5319064d4c2970a6d3be069b9c2a0e273f0f14dd | |
parent | 0d02a0d966b6d307ac33e3df3687948b74408569 (diff) | |
parent | c580180744e60d6c84fc0b59d634fcff01290780 (diff) | |
download | go-35d5cd0dcfb9d06064ec37da1621d24676454058.tar.gz go-35d5cd0dcfb9d06064ec37da1621d24676454058.zip |
[dev.boringcrypto.go1.16] all: merge go1.16.9 into dev.boringcrypto.go1.16
Change-Id: Ic26e9802fe13c491fcc26f34b8847779ac43cfe2
-rw-r--r-- | misc/wasm/wasm_exec.js | 7 | ||||
-rw-r--r-- | src/archive/zip/reader.go | 2 | ||||
-rw-r--r-- | src/archive/zip/reader_test.go | 18 | ||||
-rw-r--r-- | src/cmd/link/internal/ld/data.go | 11 | ||||
-rw-r--r-- | src/go.mod | 2 | ||||
-rw-r--r-- | src/go.sum | 4 | ||||
-rw-r--r-- | src/go/internal/gccgoimporter/gccgoinstallation_test.go | 2 | ||||
-rw-r--r-- | src/html/template/exec_test.go | 2 | ||||
-rw-r--r-- | src/net/http/h2_bundle.go | 9 | ||||
-rw-r--r-- | src/runtime/proc.go | 9 | ||||
-rw-r--r-- | src/runtime/time.go | 30 | ||||
-rw-r--r-- | src/text/template/exec.go | 9 | ||||
-rw-r--r-- | src/text/template/exec_test.go | 38 | ||||
-rw-r--r-- | src/text/template/multi_test.go | 10 | ||||
-rw-r--r-- | src/text/template/template.go | 9 | ||||
-rw-r--r-- | src/time/sleep_test.go | 67 | ||||
-rw-r--r-- | src/vendor/modules.txt | 2 |
17 files changed, 206 insertions, 25 deletions
diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js index 82041e6bb9..a0a264278b 100644 --- a/misc/wasm/wasm_exec.js +++ b/misc/wasm/wasm_exec.js @@ -564,6 +564,13 @@ offset += 8; }); + // The linker guarantees global data starts from at least wasmMinDataAddr. + // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr. + const wasmMinDataAddr = 4096 + 4096; + if (offset >= wasmMinDataAddr) { + throw new Error("command line too long"); + } + this._inst.exports.run(argc, argv); if (this.exited) { this._resolveExitPromise(); diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go index ddef2b7b5a..801d1313b6 100644 --- a/src/archive/zip/reader.go +++ b/src/archive/zip/reader.go @@ -105,7 +105,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error { // indicate it contains up to 1 << 128 - 1 files. Since each file has a // header which will be _at least_ 30 bytes we can safely preallocate // if (data size / 30) >= end.directoryRecords. - if (uint64(size)-end.directorySize)/30 >= end.directoryRecords { + if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords { z.File = make([]*File, 0, end.directoryRecords) } z.Comment = end.comment diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go index 471be27bb1..99f13345d8 100644 --- a/src/archive/zip/reader_test.go +++ b/src/archive/zip/reader_test.go @@ -1225,3 +1225,21 @@ func TestCVE202133196(t *testing.T) { t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File)) } } + +func TestCVE202139293(t *testing.T) { + // directory size is so large, that the check in Reader.init + // overflows when subtracting from the archive size, causing + // the pre-allocation check to be bypassed. + data := []byte{ + 0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, + 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, + 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff, + } + _, err := NewReader(bytes.NewReader(data), int64(len(data))) + if err != ErrFormat { + t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat) + } +} diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 52035e9630..54a1d188cd 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -2330,6 +2330,11 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64 return sect, n, va } +// On Wasm, we reserve 4096 bytes for zero page, then 4096 bytes for wasm_exec.js +// to store command line args. Data sections starts from at least address 8192. +// Keep in sync with wasm_exec.js. +const wasmMinDataAddr = 4096 + 4096 + // address assigns virtual addresses to all segments and sections and // returns all segments in file order. func (ctxt *Link) address() []*sym.Segment { @@ -2339,10 +2344,14 @@ func (ctxt *Link) address() []*sym.Segment { order = append(order, &Segtext) Segtext.Rwx = 05 Segtext.Vaddr = va - for _, s := range Segtext.Sections { + for i, s := range Segtext.Sections { va = uint64(Rnd(int64(va), int64(s.Align))) s.Vaddr = va va += s.Length + + if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr { + va = wasmMinDataAddr + } } Segtext.Length = va - uint64(*FlagTextAddr) diff --git a/src/go.mod b/src/go.mod index 798677b68c..17fc3648a3 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 - golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b + golang.org/x/net v0.0.0-20210901185431-d2e9a4ea682f golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect golang.org/x/text v0.3.4 // indirect ) diff --git a/src/go.sum b/src/go.sum index f38b3c36f0..cea3ab4134 100644 --- a/src/go.sum +++ b/src/go.sum @@ -2,8 +2,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b h1:SQCMv1JDt7RN/Vp0bjtNMSufVVHgpFVzmDFdCLL31yY= -golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210901185431-d2e9a4ea682f h1:pkBhRt1hlsctT9xYRDknb4y+e/yiacRWlnft5a4QH8Y= +golang.org/x/net v0.0.0-20210901185431-d2e9a4ea682f/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/src/go/internal/gccgoimporter/gccgoinstallation_test.go b/src/go/internal/gccgoimporter/gccgoinstallation_test.go index b332babc7b..df0188ace7 100644 --- a/src/go/internal/gccgoimporter/gccgoinstallation_test.go +++ b/src/go/internal/gccgoimporter/gccgoinstallation_test.go @@ -184,7 +184,7 @@ func TestInstallationImporter(t *testing.T) { {pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"}, {pkgpath: "math", name: "Pi", want: "const Pi untyped float"}, {pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"}, - {pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"}, + {pkgpath: "sort", name: "Search", want: "func Search(n int, f func(int) bool) int"}, {pkgpath: "unsafe", name: "Pointer", want: "type Pointer"}, } { runImporterTest(t, imp, nil, &test) diff --git a/src/html/template/exec_test.go b/src/html/template/exec_test.go index 7d1bef1782..888587335d 100644 --- a/src/html/template/exec_test.go +++ b/src/html/template/exec_test.go @@ -1720,8 +1720,6 @@ var v = "v"; ` func TestEscapeRace(t *testing.T) { - t.Skip("this test currently fails with -race; see issue #39807") - tmpl := New("") _, err := tmpl.New("templ.html").Parse(raceText) if err != nil { diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 6bef310feb..22f1e78498 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -4435,6 +4435,15 @@ func (sc *http2serverConn) serve() { case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: + // Process any written frames before reading new frames from the client since a + // written frame could have triggered a new stream to be started. + if sc.writingFrameAsync { + select { + case wroteRes := <-sc.wroteFrameCh: + sc.wroteFrame(wroteRes) + default: + } + } if !sc.processFrameFromReader(res) { return } diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 3ace2b329b..32fe877041 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -4425,7 +4425,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { return } - // On mips{,le}, 64bit atomics are emulated with spinlocks, in + // On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in // runtime/internal/atomic. If SIGPROF arrives while the program is inside // the critical section, it creates a deadlock (when writing the sample). // As a workaround, create a counter of SIGPROFs while in critical section @@ -4438,6 +4438,13 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { return } } + if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 { + // runtime/internal/atomic functions call into kernel + // helpers on arm < 7. See + // runtime/internal/atomic/sys_linux_arm.s. + cpuprof.lostAtomic++ + return + } } // Profiling runs concurrently with GC, so it must not allocate. diff --git a/src/runtime/time.go b/src/runtime/time.go index 666b242316..517a493a70 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -366,9 +366,9 @@ func deltimer(t *timer) bool { // dodeltimer removes timer i from the current P's heap. // We are locked on the P when this is called. -// It reports whether it saw no problems due to races. +// It returns the smallest changed index in pp.timers. // The caller must have locked the timers for pp. -func dodeltimer(pp *p, i int) { +func dodeltimer(pp *p, i int) int { if t := pp.timers[i]; t.pp.ptr() != pp { throw("dodeltimer: wrong P") } else { @@ -380,16 +380,18 @@ func dodeltimer(pp *p, i int) { } pp.timers[last] = nil pp.timers = pp.timers[:last] + smallestChanged := i if i != last { // Moving to i may have moved the last timer to a new parent, // so sift up to preserve the heap guarantee. - siftupTimer(pp.timers, i) + smallestChanged = siftupTimer(pp.timers, i) siftdownTimer(pp.timers, i) } if i == 0 { updateTimer0When(pp) } atomic.Xadd(&pp.numTimers, -1) + return smallestChanged } // dodeltimer0 removes timer 0 from the current P's heap. @@ -674,13 +676,14 @@ func adjusttimers(pp *p, now int64) { switch s := atomic.Load(&t.status); s { case timerDeleted: if atomic.Cas(&t.status, s, timerRemoving) { - dodeltimer(pp, i) + changed := dodeltimer(pp, i) if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { badTimer() } atomic.Xadd(&pp.deletedTimers, -1) - // Look at this heap position again. - i-- + // Go back to the earliest changed heap entry. + // "- 1" because the loop will add 1. + i = changed - 1 } case timerModifiedEarlier, timerModifiedLater: if atomic.Cas(&t.status, s, timerMoving) { @@ -690,10 +693,11 @@ func adjusttimers(pp *p, now int64) { // We don't add it back yet because the // heap manipulation could cause our // loop to skip some other timer. - dodeltimer(pp, i) + changed := dodeltimer(pp, i) moved = append(moved, t) - // Look at this heap position again. - i-- + // Go back to the earliest changed heap entry. + // "- 1" because the loop will add 1. + i = changed - 1 } case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving: badTimer() @@ -1043,7 +1047,10 @@ func timeSleepUntil() (int64, *p) { // "panic holding locks" message. Instead, we panic while not // holding a lock. -func siftupTimer(t []*timer, i int) { +// siftupTimer puts the timer at position i in the right place +// in the heap by moving it up toward the top of the heap. +// It returns the smallest changed index. +func siftupTimer(t []*timer, i int) int { if i >= len(t) { badTimer() } @@ -1063,8 +1070,11 @@ func siftupTimer(t []*timer, i int) { if tmp != t[i] { t[i] = tmp } + return i } +// siftdownTimer puts the timer at position i in the right place +// in the heap by moving it down toward the bottom of the heap. func siftdownTimer(t []*timer, i int) { n := len(t) if i >= n { diff --git a/src/text/template/exec.go b/src/text/template/exec.go index 19154fc640..ba01a15b22 100644 --- a/src/text/template/exec.go +++ b/src/text/template/exec.go @@ -179,10 +179,7 @@ func errRecover(errp *error) { // A template may be executed safely in parallel, although if parallel // executions share a Writer the output may be interleaved. func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { - var tmpl *Template - if t.common != nil { - tmpl = t.tmpl[name] - } + tmpl := t.Lookup(name) if tmpl == nil { return fmt.Errorf("template: no template %q associated with template %q", name, t.name) } @@ -230,6 +227,8 @@ func (t *Template) DefinedTemplates() string { return "" } var b strings.Builder + t.muTmpl.RLock() + defer t.muTmpl.RUnlock() for name, tmpl := range t.tmpl { if tmpl.Tree == nil || tmpl.Root == nil { continue @@ -401,7 +400,7 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) { s.at(t) - tmpl := s.tmpl.tmpl[t.Name] + tmpl := s.tmpl.Lookup(t.Name) if tmpl == nil { s.errorf("template %q not defined", t.Name) } diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 1a129ed5af..78abc25d65 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -12,6 +12,7 @@ import ( "io" "reflect" "strings" + "sync" "testing" ) @@ -1710,3 +1711,40 @@ func TestIssue43065(t *testing.T) { t.Errorf("%s", err) } } + +// Issue 39807: data race in html/template & text/template +func TestIssue39807(t *testing.T) { + var wg sync.WaitGroup + + tplFoo, err := New("foo").Parse(`{{ template "bar" . }}`) + if err != nil { + t.Error(err) + } + + tplBar, err := New("bar").Parse("bar") + if err != nil { + t.Error(err) + } + + gofuncs := 10 + numTemplates := 10 + + for i := 1; i <= gofuncs; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for j := 0; j < numTemplates; j++ { + _, err := tplFoo.AddParseTree(tplBar.Name(), tplBar.Tree) + if err != nil { + t.Error(err) + } + err = tplFoo.Execute(io.Discard, nil) + if err != nil { + t.Error(err) + } + } + }() + } + + wg.Wait() +} diff --git a/src/text/template/multi_test.go b/src/text/template/multi_test.go index b543ab5c47..6b81ffe7ac 100644 --- a/src/text/template/multi_test.go +++ b/src/text/template/multi_test.go @@ -452,3 +452,13 @@ func TestIssue19294(t *testing.T) { } } } + +// Issue 48436 +func TestAddToZeroTemplate(t *testing.T) { + tree, err := parse.Parse("c", cloneText3, "", "", nil, builtins()) + if err != nil { + t.Fatal(err) + } + var tmpl Template + tmpl.AddParseTree("x", tree["c"]) +} diff --git a/src/text/template/template.go b/src/text/template/template.go index ec26eb4c50..776be9cd07 100644 --- a/src/text/template/template.go +++ b/src/text/template/template.go @@ -13,6 +13,7 @@ import ( // common holds the information shared by related templates. type common struct { tmpl map[string]*Template // Map from name to defined templates. + muTmpl sync.RWMutex // protects tmpl option option // We use two maps, one for parsing and one for execution. // This separation makes the API cleaner since it doesn't @@ -88,6 +89,8 @@ func (t *Template) Clone() (*Template, error) { if t.common == nil { return nt, nil } + t.muTmpl.RLock() + defer t.muTmpl.RUnlock() for k, v := range t.tmpl { if k == t.name { nt.tmpl[t.name] = nt @@ -125,6 +128,8 @@ func (t *Template) copy(c *common) *Template { // definition is replaced; otherwise a new template is created, defined, and returned. func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { t.init() + t.muTmpl.Lock() + defer t.muTmpl.Unlock() nt := t if name != t.name { nt = t.New(name) @@ -142,6 +147,8 @@ func (t *Template) Templates() []*Template { return nil } // Return a slice so we don't expose the map. + t.muTmpl.RLock() + defer t.muTmpl.RUnlock() m := make([]*Template, 0, len(t.tmpl)) for _, v := range t.tmpl { m = append(m, v) @@ -182,6 +189,8 @@ func (t *Template) Lookup(name string) *Template { if t.common == nil { return nil } + t.muTmpl.RLock() + defer t.muTmpl.RUnlock() return t.tmpl[name] } diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go index e0172bf5e0..c48e704eb7 100644 --- a/src/time/sleep_test.go +++ b/src/time/sleep_test.go @@ -7,6 +7,7 @@ package time_test import ( "errors" "fmt" + "math/rand" "runtime" "strings" "sync" @@ -561,6 +562,72 @@ func TestTimerModifiedEarlier(t *testing.T) { } } +// Test that rapidly moving timers earlier and later doesn't cause +// some of the sleep times to be lost. +// Issue 47762 +func TestAdjustTimers(t *testing.T) { + var rnd = rand.New(rand.NewSource(Now().UnixNano())) + + timers := make([]*Timer, 100) + states := make([]int, len(timers)) + indices := rnd.Perm(len(timers)) + + for len(indices) != 0 { + var ii = rnd.Intn(len(indices)) + var i = indices[ii] + + var timer = timers[i] + var state = states[i] + states[i]++ + + switch state { + case 0: + timers[i] = NewTimer(0) + case 1: + <-timer.C // Timer is now idle. + + // Reset to various long durations, which we'll cancel. + case 2: + if timer.Reset(1 * Minute) { + panic("shouldn't be active (1)") + } + case 4: + if timer.Reset(3 * Minute) { + panic("shouldn't be active (3)") + } + case 6: + if timer.Reset(2 * Minute) { + panic("shouldn't be active (2)") + } + + // Stop and drain a long-duration timer. + case 3, 5, 7: + if !timer.Stop() { + t.Logf("timer %d state %d Stop returned false", i, state) + <-timer.C + } + + // Start a short-duration timer we expect to select without blocking. + case 8: + if timer.Reset(0) { + t.Fatal("timer.Reset returned true") + } + case 9: + now := Now() + <-timer.C + dur := Since(now) + if dur > 750*Millisecond { + t.Errorf("timer %d took %v to complete", i, dur) + } + + // Timer is done. Swap with tail and remove. + case 10: + indices[ii] = indices[len(indices)-1] + indices = indices[:len(indices)-1] + } + } +} + // Benchmark timer latency when the thread that creates the timer is busy with // other work and the timers must be serviced by other threads. // https://golang.org/issue/38860 diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt index b18d36639a..061e0acb59 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519 golang.org/x/crypto/hkdf golang.org/x/crypto/internal/subtle golang.org/x/crypto/poly1305 -# golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b +# golang.org/x/net v0.0.0-20210901185431-d2e9a4ea682f ## explicit golang.org/x/net/dns/dnsmessage golang.org/x/net/http/httpguts |