mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/gc: pad structs which end in zero-sized fields
For a non-zero-sized struct with a final zero-sized field, add a byte to the size (before rounding to alignment). This change ensures that taking the address of the zero-sized field will not incorrectly leak the following object in memory. reflect.funcLayout also needs this treatment. Fixes #9401 Change-Id: I1dc503dc5af4ca22c8f8c048fb7b4541cc957e0f Reviewed-on: https://go-review.googlesource.com/2452 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
654a185f20
commit
6f07ac2f28
3 changed files with 69 additions and 8 deletions
|
|
@ -1527,9 +1527,10 @@ func isReflexive(t *rtype) bool {
|
|||
|
||||
// gcProg is a helper type for generatation of GC pointer info.
|
||||
type gcProg struct {
|
||||
gc []byte
|
||||
size uintptr // size of type in bytes
|
||||
hasPtr bool
|
||||
gc []byte
|
||||
size uintptr // size of type in bytes
|
||||
hasPtr bool
|
||||
lastZero uintptr // largest offset of a zero-byte field
|
||||
}
|
||||
|
||||
func (gc *gcProg) append(v byte) {
|
||||
|
|
@ -1542,6 +1543,9 @@ func (gc *gcProg) appendProg(t *rtype) {
|
|||
gc.align(uintptr(t.align))
|
||||
if !t.pointers() {
|
||||
gc.size += t.size
|
||||
if t.size == 0 {
|
||||
gc.lastZero = gc.size
|
||||
}
|
||||
return
|
||||
}
|
||||
switch t.Kind() {
|
||||
|
|
@ -1566,11 +1570,15 @@ func (gc *gcProg) appendProg(t *rtype) {
|
|||
gc.appendWord(bitsPointer)
|
||||
gc.appendWord(bitsPointer)
|
||||
case Struct:
|
||||
oldsize := gc.size
|
||||
c := t.NumField()
|
||||
for i := 0; i < c; i++ {
|
||||
gc.appendProg(t.Field(i).Type.common())
|
||||
}
|
||||
gc.align(uintptr(t.align))
|
||||
if gc.size > oldsize + t.size {
|
||||
panic("reflect: struct components are larger than the struct itself")
|
||||
}
|
||||
gc.size = oldsize + t.size
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1595,6 +1603,9 @@ func (gc *gcProg) finalize() (unsafe.Pointer, bool) {
|
|||
if gc.size == 0 {
|
||||
return nil, false
|
||||
}
|
||||
if gc.lastZero == gc.size {
|
||||
gc.size++
|
||||
}
|
||||
ptrsize := unsafe.Sizeof(uintptr(0))
|
||||
gc.align(ptrsize)
|
||||
nptr := gc.size / ptrsize
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue