]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/buildid: don't crash on 0 phdr.p_align field
authorIan Lance Taylor <iant@golang.org>
Thu, 17 Aug 2023 20:03:21 +0000 (13:03 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 17 Aug 2023 20:40:42 +0000 (20:40 +0000)
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>

src/cmd/internal/buildid/buildid_test.go
src/cmd/internal/buildid/note.go

index 55835bf8acafed4f65b187f99557c2e11e10cfb0..8efa47346c3259b12751142ec23a88efaf3864fc 100644 (file)
@@ -7,6 +7,8 @@ package buildid
 import (
        "bytes"
        "crypto/sha256"
+       "debug/elf"
+       "encoding/binary"
        "internal/obscuretestdata"
        "os"
        "reflect"
@@ -90,6 +92,69 @@ func TestReadFile(t *testing.T) {
                if id != newID || err != nil {
                        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
+                       }
+               }
        }
 }
 
index ab98701fb569f22ba0c4da7a9091da6e413e395e..e0e8683c8efcea81f15f6a4ebbe29651cbe3f10f 100644 (file)
@@ -153,9 +153,11 @@ func readELF(name string, f *os.File, data []byte) (buildid string, err error) {
                        }
                        off += notesz
                        align := p.Align
-                       alignedOff := (off + align - 1) &^ (align - 1)
-                       notesz += alignedOff - off
-                       off = alignedOff
+                       if align != 0 {
+                               alignedOff := (off + align - 1) &^ (align - 1)
+                               notesz += alignedOff - off
+                               off = alignedOff
+                       }
                        filesz -= notesz
                        note = note[notesz:]
                }