diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
commit | 47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch) | |
tree | a61a0ffd83f4a3def4b36e5c8e99630c559aa723 /test/fixedbugs/issue29312.go | |
parent | Initial commit. (diff) | |
download | golang-1.18-upstream.tar.xz golang-1.18-upstream.zip |
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | test/fixedbugs/issue29312.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/test/fixedbugs/issue29312.go b/test/fixedbugs/issue29312.go new file mode 100644 index 0000000..4293e01 --- /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)) + } +} |