From: Alex Brainman Date: Tue, 24 Jun 2025 05:18:28 +0000 (+1000) Subject: debug/pe: avoid panic in File.ImportedSymbols X-Git-Tag: go1.26rc2~7^2~47 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2cd0371a0a61e0dec6034239b1a92a20968c8522;p=gostls13.git debug/pe: avoid panic in File.ImportedSymbols This change skips symbols where dt.OriginalFirstThunk is less than ds.VirtualAddress. The variable types are uint32, and (dt.OriginalFirstThunk-ds.VirtualAddress) becomes very large number when dt.OriginalFirstThunk < ds.VirtualAddress. Fixes #73548. Fixes #76721. Fixes #76724. Change-Id: I72908bd0896003423aeb754fa0b6c72d452cdb4e Reviewed-on: https://go-review.googlesource.com/c/go/+/684495 LUCI-TryBot-Result: Go LUCI Reviewed-by: Emmanuel Odeke Reviewed-by: Ian Lance Taylor Reviewed-by: Cherry Mui Reviewed-by: Michael Knyszek --- diff --git a/src/debug/pe/file.go b/src/debug/pe/file.go index ed63a11cb6..91b7d1dca1 100644 --- a/src/debug/pe/file.go +++ b/src/debug/pe/file.go @@ -379,7 +379,11 @@ func (f *File) ImportedSymbols() ([]string, error) { } // seek to the virtual address specified in the import data directory - d = d[idd.VirtualAddress-ds.VirtualAddress:] + seek := idd.VirtualAddress - ds.VirtualAddress + if seek >= uint32(len(d)) { + return nil, errors.New("optional header data directory virtual size doesn't fit within data seek") + } + d = d[seek:] // start decoding the import directory var ida []ImportDirectory @@ -408,9 +412,16 @@ func (f *File) ImportedSymbols() ([]string, error) { dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress)) d, _ = ds.Data() // seek to OriginalFirstThunk - d = d[dt.OriginalFirstThunk-ds.VirtualAddress:] + seek := dt.OriginalFirstThunk - ds.VirtualAddress + if seek >= uint32(len(d)) { + return nil, errors.New("import directory original first thunk doesn't fit within data seek") + } + d = d[seek:] for len(d) > 0 { if pe64 { // 64bit + if len(d) < 8 { + return nil, errors.New("thunk parsing needs at least 8-bytes") + } va := binary.LittleEndian.Uint64(d[0:8]) d = d[8:] if va == 0 { @@ -423,6 +434,9 @@ func (f *File) ImportedSymbols() ([]string, error) { all = append(all, fn+":"+dt.dll) } } else { // 32bit + if len(d) <= 4 { + return nil, errors.New("thunk parsing needs at least 5-bytes") + } va := binary.LittleEndian.Uint32(d[0:4]) d = d[4:] if va == 0 {