]> Cypherpunks repositories - gostls13.git/commitdiff
debug/pe: avoid panic in File.ImportedSymbols
authorAlex Brainman <alex.brainman@gmail.com>
Tue, 24 Jun 2025 05:18:28 +0000 (15:18 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 23 Dec 2025 03:38:37 +0000 (19:38 -0800)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/debug/pe/file.go

index ed63a11cb6e98c30eb9c3762d4721f65e65d9229..91b7d1dca1ba015150b683134c3777788ce652fa 100644 (file)
@@ -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 {