Bug 1423821 - Add a consistency check for section offsets to elfhack. draft
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 07 Dec 2017 15:34:58 +0900
changeset 710934 c93a0a540a235fa732241e45a5b99623ba1060d6
parent 710933 85ac260058e3d34cba682f38e1712fbcac003e26
child 743702 2ccfda98dc9d76e61d57e3e79f267b48acaec889
push id92952
push userbmo:mh+mozilla@glandium.org
push dateTue, 12 Dec 2017 22:18:13 +0000
bugs1423821
milestone59.0a1
Bug 1423821 - Add a consistency check for section offsets to elfhack. lld is being too smart for its own good, and places non-relocatable data right after the program headers, which prevents the program headers from growing. But elfhack wasn't checking for that, so happily placed the non-relocatable data at its non-relocated location, overwriting the last item of the program headers.
build/unix/elfhack/elf.cpp
--- a/build/unix/elfhack/elf.cpp
+++ b/build/unix/elfhack/elf.cpp
@@ -415,16 +415,28 @@ void Elf::normalize()
         phdr_section->getNext()->markDirty();
     }
     // fixup shdr before writing
     if (ehdr->e_shnum != shdr_section->getSize() / shdr_section->getEntSize())
         shdr_section->getShdr().sh_size = ehdr->e_shnum * Elf_Shdr::size(ehdr->e_ident[EI_CLASS]);
     ehdr->e_shoff = shdr_section->getOffset();
     ehdr->e_entry = eh_entry.getValue();
     ehdr->e_shstrndx = eh_shstrndx->getIndex();
+
+    // Check sections consistency
+    unsigned int minOffset = 0;
+    for (ElfSection *section = ehdr; section != nullptr; section = section->getNext()) {
+        unsigned int offset = section->getOffset();
+        if (offset < minOffset) {
+           throw std::runtime_error("Sections overlap");
+        }
+        if (section->getType() != SHT_NOBITS) {
+           minOffset = offset + section->getSize();
+        }
+    }
 }
 
 void Elf::write(std::ofstream &file)
 {
     normalize();
     for (ElfSection *section = ehdr;
          section != nullptr; section = section->getNext()) {
         file.seekp(section->getOffset());