From: Ian Lance Taylor Date: Fri, 24 Jun 2022 17:24:11 +0000 (-0700) Subject: debug/pe: use saferio to set symbol slice capacity X-Git-Tag: go1.20rc1~1556 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=760c180d3bb2464b1e91402630c8f0d1e79180b3;p=gostls13.git debug/pe: use saferio to set symbol slice capacity No test case because the problem can only happen for invalid data. Let the fuzzer find cases like this. For #47653 Fixes #53530 Change-Id: If1cebbbcabb188fec8be30ef043c8c4c935a9564 Reviewed-on: https://go-review.googlesource.com/c/go/+/413995 Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Alex Brainman Reviewed-by: Bryan Mills --- diff --git a/src/debug/pe/symbol.go b/src/debug/pe/symbol.go index 86a1fbc301..0a5343f925 100644 --- a/src/debug/pe/symbol.go +++ b/src/debug/pe/symbol.go @@ -6,7 +6,9 @@ package pe import ( "encoding/binary" + "errors" "fmt" + "internal/saferio" "io" "unsafe" ) @@ -57,29 +59,35 @@ func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) { if err != nil { return nil, fmt.Errorf("fail to seek to symbol table: %v", err) } - syms := make([]COFFSymbol, fh.NumberOfSymbols) + c := saferio.SliceCap(COFFSymbol{}, uint64(fh.NumberOfSymbols)) + if c < 0 { + return nil, errors.New("too many symbols; file may be corrupt") + } + syms := make([]COFFSymbol, 0, c) naux := 0 - for k := range syms { + for k := uint32(0); k < fh.NumberOfSymbols; k++ { + var sym COFFSymbol if naux == 0 { // Read a primary symbol. - err = binary.Read(r, binary.LittleEndian, &syms[k]) + err = binary.Read(r, binary.LittleEndian, &sym) if err != nil { return nil, fmt.Errorf("fail to read symbol table: %v", err) } // Record how many auxiliary symbols it has. - naux = int(syms[k].NumberOfAuxSymbols) + naux = int(sym.NumberOfAuxSymbols) } else { // Read an aux symbol. At the moment we assume all // aux symbols are format 5 (obviously this doesn't always // hold; more cases will be needed below if more aux formats // are supported in the future). naux-- - aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&syms[k])) + aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&sym)) err = binary.Read(r, binary.LittleEndian, aux) if err != nil { return nil, fmt.Errorf("fail to read symbol table: %v", err) } } + syms = append(syms, sym) } if naux != 0 { return nil, fmt.Errorf("fail to read symbol table: %d aux symbols unread", naux)