Skip to content

debug/elf: NewFile fails to parse ELF files with program header count overflow (PN_XNUM) #78217

@578559967

Description

@578559967

What version of Go are you using (go version)?

go1.26rc1 (also affects earlier versions)

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you are using?

Linux/amd64

What did you do?

I tried to parse a core dump file that contains 74,525 program headers using debug/elf.NewFile. The ELF header's e_phnum field overflows to PN_XNUM (0xffff), and the actual count is stored in the first section header's sh_info field per ELF specification.

What did you expect to see?

NewFile should correctly parse all 74,525 program headers.

What did you see instead?

Only 65,536 (0x10000) program headers were parsed, causing the core file to be incorrectly read.

Root Cause

According to the ELF Specification:

e_phnum: If the number of program headers is greater than or equal to PN_XNUM (0xffff), this member has the value PN_XNUM and the actual number of program headers is contained in the sh_info field of the section header at index 0.

However, the current implementation in src/debug/elf/file.go simply reads e_phnum as a uint16 without checking for the overflow case:

// file.go:349, 368
phnum = int(bo.Uint16(data[unsafe.Offsetof(hdr.Phnum):]))

Comparison with Section Header Overflow
The code already correctly handles section header overflow (shnum >= SHN_LORESERVE) in commit 7d157fd:

// file.go:453-493 - Already implemented
if shoff > 0 && shnum == 0 {
    // Read actual shnum from section[0].sh_size
    shnum = int(sh.Size)
}

But the equivalent logic for phnum overflow is missing.

Suggested Fix

Add similar overflow handling for phnum after reading the ELF header:

const PN_XNUM = 0xffff
// After reading phnum from ELF header
if phnum == PN_XNUM && shoff > 0 {
    // Read actual phnum from section[0].sh_info
    var shInfo uint32
    switch f.Class {
    case ELFCLASS32:
        var sh Section32
        // ... read section header at index 0
        shInfo = sh.Info
    case ELFCLASS64:
        var sh Section64
        // ... read section header at index 0
        shInfo = sh.Info
    }
    phnum = int(shInfo)
}

Impact

This affects parsing of:

  • Large core dump files
  • Any ELF files with >= 65535 program headers

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.FixPendingIssues that have a fix which has not yet been reviewed or submitted.NeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions