From 2b53b4bea611824a933123780357b5a2cbe2ed0f Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 9 Oct 2018 21:41:53 +0000 Subject: [PATCH] Attempt to fix ubsan. Previously, we cast a pointer to Elf{32,64}_Chdr like this auto *Hdr = reinterpret_cast(Ptr); and read from its members like this read32(&Hdr->ch_size); I was thinking that this does not violate alignment requirement, since &Hdr->ch_size doesn't really access memory, but seems like it is a violation in terms of C++ spec (?) In this patch, I use a different struct that allows unaligned access. llvm-svn: 344083 --- lld/ELF/InputSection.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 605d55b..9da4af6 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -206,6 +206,9 @@ OutputSection *SectionBase::getOutputSection() { // by zlib-compressed data. This function parses a header to initialize // `UncompressedSize` member and remove the header from `RawData`. void InputSectionBase::parseCompressedHeader() { + typedef typename ELF64LE::Chdr Chdr64; + typedef typename ELF32LE::Chdr Chdr32; + // Old-style header if (Name.startswith(".zdebug")) { if (!toStringRef(RawData).startswith("ZLIB")) { @@ -233,35 +236,35 @@ void InputSectionBase::parseCompressedHeader() { // New-style 64-bit header if (Config->Is64) { - if (RawData.size() < sizeof(Elf64_Chdr)) { + if (RawData.size() < sizeof(Chdr64)) { error(toString(this) + ": corrupted compressed section"); return; } - auto *Hdr = reinterpret_cast(RawData.data()); - if (read32(&Hdr->ch_type) != ELFCOMPRESS_ZLIB) { + auto *Hdr = reinterpret_cast(RawData.data()); + if (Hdr->ch_type != ELFCOMPRESS_ZLIB) { error(toString(this) + ": unsupported compression type"); return; } - UncompressedSize = read64(&Hdr->ch_size); + UncompressedSize = Hdr->ch_size; RawData = RawData.slice(sizeof(*Hdr)); return; } // New-style 32-bit header - if (RawData.size() < sizeof(Elf32_Chdr)) { + if (RawData.size() < sizeof(Chdr32)) { error(toString(this) + ": corrupted compressed section"); return; } - auto *Hdr = reinterpret_cast(RawData.data()); - if (read32(&Hdr->ch_type) != ELFCOMPRESS_ZLIB) { + auto *Hdr = reinterpret_cast(RawData.data()); + if (Hdr->ch_type != ELFCOMPRESS_ZLIB) { error(toString(this) + ": unsupported compression type"); return; } - UncompressedSize = read32(&Hdr->ch_size); + UncompressedSize = Hdr->ch_size; RawData = RawData.slice(sizeof(*Hdr)); } -- 2.7.4