1
0
mirror of https://github.com/golang/go synced 2024-11-23 10:30:03 -07:00

cmd/internal/buildid: don't crash on 0 phdr.p_align field

A 0 in phdr.p_align is the same as 1, meaning no alignment.

Fixes #62097

Change-Id: I931bab443fd6a89b5b45c8f99ead217f02e9b453
Reviewed-on: https://go-review.googlesource.com/c/go/+/520597
Auto-Submit: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Ian Lance Taylor 2023-08-17 13:03:21 -07:00 committed by Gopher Robot
parent b75ac7a8d5
commit 11390998ff
2 changed files with 70 additions and 3 deletions

View File

@ -7,6 +7,8 @@ package buildid
import ( import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"debug/elf"
"encoding/binary"
"internal/obscuretestdata" "internal/obscuretestdata"
"os" "os"
"reflect" "reflect"
@ -90,6 +92,69 @@ func TestReadFile(t *testing.T) {
if id != newID || err != nil { if id != newID || err != nil {
t.Errorf("ReadFile(%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID) t.Errorf("ReadFile(%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID)
} }
// Test an ELF PT_NOTE segment with an Align field of 0.
// Do this by rewriting the file data.
if strings.Contains(name, "elf") {
// We only expect a 64-bit ELF file.
if elf.Class(data[elf.EI_CLASS]) != elf.ELFCLASS64 {
continue
}
// We only expect a little-endian ELF file.
if elf.Data(data[elf.EI_DATA]) != elf.ELFDATA2LSB {
continue
}
order := binary.LittleEndian
var hdr elf.Header64
if err := binary.Read(bytes.NewReader(data), order, &hdr); err != nil {
t.Error(err)
continue
}
phoff := hdr.Phoff
phnum := int(hdr.Phnum)
phsize := uint64(hdr.Phentsize)
for i := 0; i < phnum; i++ {
var phdr elf.Prog64
if err := binary.Read(bytes.NewReader(data[phoff:]), order, &phdr); err != nil {
t.Error(err)
continue
}
if elf.ProgType(phdr.Type) == elf.PT_NOTE {
// Increase the size so we keep
// reading notes.
order.PutUint64(data[phoff+4*8:], phdr.Filesz+1)
// Clobber the Align field to zero.
order.PutUint64(data[phoff+6*8:], 0)
// Clobber the note type so we
// keep reading notes.
order.PutUint32(data[phdr.Off+12:], 0)
}
phoff += phsize
}
if err := os.WriteFile(tmp, data, 0666); err != nil {
t.Error(err)
continue
}
id, err := ReadFile(tmp)
// Because we clobbered the note type above,
// we don't expect to see a Go build ID.
// The issue we are testing for was a crash
// in Readefile; see issue #62097.
if id != "" || err != nil {
t.Errorf("ReadFile with zero ELF Align = %q, %v, want %q, nil", id, err, "")
continue
}
}
} }
} }

View File

@ -153,9 +153,11 @@ func readELF(name string, f *os.File, data []byte) (buildid string, err error) {
} }
off += notesz off += notesz
align := p.Align align := p.Align
if align != 0 {
alignedOff := (off + align - 1) &^ (align - 1) alignedOff := (off + align - 1) &^ (align - 1)
notesz += alignedOff - off notesz += alignedOff - off
off = alignedOff off = alignedOff
}
filesz -= notesz filesz -= notesz
note = note[notesz:] note = note[notesz:]
} }