debug/pe, debug/macho: use saferio.ReadData for ZLIB section decompression

Both debug/pe and debug/macho use make([]byte, dlen) where dlen is
read directly from the binary header as a uint64. A crafted binary
with a large dlen value causes an out-of-memory panic because the
runtime attempts to allocate the full attacker-controlled size before
reading any compressed data.

Replace the make+io.ReadFull pattern with saferio.ReadData, which
incrementally grows the buffer while reading. This is the same
approach used by debug/elf (CL 765061).

Fixes #79315

Change-Id: Iaef7bcf3c7466215d65bcc15c5593c412773b9d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/776620
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
haru yama (Character) 2026-05-11 03:49:34 -07:00 committed by Gopher Robot
parent f552547748
commit a5a336cda2
2 changed files with 5 additions and 4 deletions

View file

@ -646,12 +646,12 @@ func (f *File) DWARF() (*dwarf.Data, error) {
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
dlen := binary.BigEndian.Uint64(b[4:12])
dbuf := make([]byte, dlen)
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
if err != nil {
return nil, err
}
if _, err := io.ReadFull(r, dbuf); err != nil {
dbuf, err := saferio.ReadData(r, dlen)
if err != nil {
return nil, err
}
if err := r.Close(); err != nil {

View file

@ -22,6 +22,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"internal/saferio"
"io"
"os"
"strings"
@ -239,12 +240,12 @@ func (f *File) DWARF() (*dwarf.Data, error) {
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
dlen := binary.BigEndian.Uint64(b[4:12])
dbuf := make([]byte, dlen)
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
if err != nil {
return nil, err
}
if _, err := io.ReadFull(r, dbuf); err != nil {
dbuf, err := saferio.ReadData(r, dlen)
if err != nil {
return nil, err
}
if err := r.Close(); err != nil {