From 338df53621abdcf4cd6043473170af1e5b719277 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 11 Apr 2022 18:42:34 -0700 Subject: [PATCH] symbols_map: allow unexpected EOF in ELF files Some of the prebuilt ELF files used for bionic heads cause an unexpected EOF error, ignore unexpected EOF the same way we do for EOF. Test: not yet Change-Id: I267d11b4d12b83ecebedc72a565e148c5e53af6d --- cmd/symbols_map/elf.go | 6 +++--- cmd/symbols_map/elf_test.go | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/cmd/symbols_map/elf.go b/cmd/symbols_map/elf.go index 3c8b1e42b..950e3b246 100644 --- a/cmd/symbols_map/elf.go +++ b/cmd/symbols_map/elf.go @@ -38,13 +38,13 @@ func elfIdentifier(filename string, allowMissing bool) (string, error) { return elfIdentifierFromReaderAt(f, filename, allowMissing) } -// elfIdentifier extracts the elf build ID from a ReaderAt. If allowMissing is true it returns -// an empty identifier if the file exists but the build ID note does not. +// elfIdentifierFromReaderAt extracts the elf build ID from a ReaderAt. If allowMissing is true it +// returns an empty identifier if the file exists but the build ID note does not. func elfIdentifierFromReaderAt(r io.ReaderAt, filename string, allowMissing bool) (string, error) { f, err := elf.NewFile(r) if err != nil { if allowMissing { - if errors.Is(err, io.EOF) { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { return "", nil } if _, ok := err.(*elf.FormatError); ok { diff --git a/cmd/symbols_map/elf_test.go b/cmd/symbols_map/elf_test.go index b96ea592c..a94c87f21 100644 --- a/cmd/symbols_map/elf_test.go +++ b/cmd/symbols_map/elf_test.go @@ -39,6 +39,10 @@ func Test_elfIdentifierFromReaderAt_BadElfFile(t *testing.T) { name: "empty elf", contents: emptyElfFile(), }, + { + name: "short section header", + contents: shortSectionHeaderElfFile(), + }, } for _, tt := range tests { @@ -111,3 +115,38 @@ func emptyElfFile() string { binary.Write(buf, binary.LittleEndian, header) return buf.String() } + +// shortSectionHeader returns an elf file header with a section header that extends past the end of +// the file. +func shortSectionHeaderElfFile() string { + ident := [elf.EI_NIDENT]byte{} + identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT]) + binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF")) + binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64) + binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB) + binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT) + binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX) + binary.Write(identBuf, binary.LittleEndian, make([]byte, 8)) + + header := elf.Header64{ + Ident: ident, + Type: uint16(elf.ET_EXEC), + Machine: uint16(elf.EM_X86_64), + Version: uint32(elf.EV_CURRENT), + Entry: 0, + Phoff: uint64(binary.Size(elf.Header64{})), + Shoff: uint64(binary.Size(elf.Header64{})), + Flags: 0, + Ehsize: uint16(binary.Size(elf.Header64{})), + Phentsize: 0x38, + Phnum: 0, + Shentsize: 0x40, + Shnum: 1, + Shstrndx: 0, + } + + buf := &bytes.Buffer{} + binary.Write(buf, binary.LittleEndian, header) + binary.Write(buf, binary.LittleEndian, []byte{0}) + return buf.String() +}