From ccd992355df7192993c666236047820244914598 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 16 Apr 2024 21:19:13 +0200 Subject: Adding upstream version 1.21.8. Signed-off-by: Daniel Baumann --- test/fixedbugs/issue29312.go | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test/fixedbugs/issue29312.go (limited to 'test/fixedbugs/issue29312.go') diff --git a/test/fixedbugs/issue29312.go b/test/fixedbugs/issue29312.go new file mode 100644 index 0000000..cbf79f7 --- /dev/null +++ b/test/fixedbugs/issue29312.go @@ -0,0 +1,70 @@ +// run + +// Copyright 2020 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. + +// This test is not for a fix of 29312 proper, but for the patch that +// makes sure we at least don't have a security hole because of 29312. + +// This code generates lots of types. The binary should contain +// a runtime.slicetype for each of the following 253 types: +// +// []*pwn +// [][]*pwn +// ... +// [][]...[][]*pwn - 249 total "[]" +// [][]...[][][]*pwn - 250 total "[]" +// [][]...[][][][]*pwn - 251 total "[]" +// [][]...[][][][][]*pwn - 252 total "[]" +// [][]...[][][][][][]*pwn - 253 total "[]" +// +// The type names for these types are as follows. Because we truncate +// the name at depth 250, the last few names are all identical: +// +// type:[]*"".pwn +// type:[][]*"".pwn +// ... +// type:[][]...[][]*pwn - 249 total "[]" +// type:[][]...[][][]*<...> - 250 total "[]" +// type:[][]...[][][][]<...> - 251 total "[]" +// type:[][]...[][][][]<...> - 252 total "[]" (but only 251 "[]" in the name) +// type:[][]...[][][][]<...> - 253 total "[]" (but only 251 "[]" in the name) +// +// Because the names of the last 3 types are all identical, the +// compiler will generate only a single runtime.slicetype data +// structure for all 3 underlying types. It turns out the compiler +// generates just the 251-entry one. There aren't any +// runtime.slicetypes generated for the final two types. +// +// The compiler passes type:[]...[]<...> (251 total "[]") to +// fmt.Sprintf (instead of the correct 253 one). But the data +// structure at runtime actually has 253 nesting levels. So we end up +// calling String on something that is of type [][]*pwn instead of +// something of type *pwn. The way arg passing in Go works, the +// backing store pointer for the outer slice becomes the "this" +// pointer of the String method, which points to the inner []*pwn +// slice. The String method then modifies the length of that inner +// slice. +package main + +import "fmt" + +type pwn struct { + a [3]uint +} + +func (this *pwn) String() string { + this.a[1] = 7 // update length + return "" +} + +func main() { + var a pwn + s := [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]*pwn{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{&a}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} // depth 253 + fmt.Sprint(s) + n := len(s[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]) // depth 252, type []*pwn + if n != 1 { + panic(fmt.Sprintf("length was changed, want 1 got %d", n)) + } +} -- cgit v1.2.3