[llvm] 657f02d - Revert "Extract LC_CODE_SIGNATURE related implementation out of LLD"

Daniel Rodríguez Troitiño via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 1 17:21:43 PDT 2021


Author: Daniel Rodríguez Troitiño
Date: 2021-10-01T17:19:50-07:00
New Revision: 657f02d45804b1b17aeec8cd887350e9f05ab6da

URL: https://github.com/llvm/llvm-project/commit/657f02d45804b1b17aeec8cd887350e9f05ab6da
DIFF: https://github.com/llvm/llvm-project/commit/657f02d45804b1b17aeec8cd887350e9f05ab6da.diff

LOG: Revert "Extract LC_CODE_SIGNATURE related implementation out of LLD"

This reverts commit cc8229603b67763e77a46894f88f7d3ddd04de34.

As discussed in the review of https://reviews.llvm.org/D109972, this was not
right approach, so we are reverting to start with a different approach.

Differential Revision: https://reviews.llvm.org/D110974

Added: 
    

Modified: 
    lld/MachO/SyntheticSections.cpp
    lld/MachO/SyntheticSections.h
    llvm/include/llvm/Object/MachO.h
    llvm/lib/Object/CMakeLists.txt

Removed: 
    llvm/lib/Object/CodeSignatureSection.cpp


################################################################################
diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index b03810dc2c5ca..61fbf7487cc0d 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -24,6 +24,11 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/SHA256.h"
+
+#if defined(__APPLE__)
+#include <sys/mman.h>
+#endif
 
 #ifdef LLVM_HAVE_LIBXAR
 #include <fcntl.h>
@@ -1146,30 +1151,97 @@ void StringTableSection::writeTo(uint8_t *buf) const {
   }
 }
 
+static_assert((CodeSignatureSection::blobHeadersSize % 8) == 0, "");
+static_assert((CodeSignatureSection::fixedHeadersSize % 8) == 0, "");
+
 CodeSignatureSection::CodeSignatureSection()
     : LinkEditSection(segment_names::linkEdit, section_names::codeSignature) {
-  align = object::CodeSignatureSection::Align; // required by libstuff
+  align = 16; // required by libstuff
+  // FIXME: Consider using finalOutput instead of outputFile.
+  fileName = config->outputFile;
+  size_t slashIndex = fileName.rfind("/");
+  if (slashIndex != std::string::npos)
+    fileName = fileName.drop_front(slashIndex + 1);
+  allHeadersSize = alignTo<16>(fixedHeadersSize + fileName.size() + 1);
+  fileNamePad = allHeadersSize - fixedHeadersSize - fileName.size();
+}
+
+uint32_t CodeSignatureSection::getBlockCount() const {
+  return (fileOff + blockSize - 1) / blockSize;
 }
 
 uint64_t CodeSignatureSection::getRawSize() const {
-  return static_cast<uint64_t>(sectionBuilder->getRawSize());
+  return allHeadersSize + getBlockCount() * hashSize;
 }
 
 void CodeSignatureSection::writeHashes(uint8_t *buf) const {
-  sectionBuilder->write(buf);
+  uint8_t *code = buf;
+  uint8_t *codeEnd = buf + fileOff;
+  uint8_t *hashes = codeEnd + allHeadersSize;
+  while (code < codeEnd) {
+    StringRef block(reinterpret_cast<char *>(code),
+                    std::min(codeEnd - code, static_cast<ssize_t>(blockSize)));
+    SHA256 hasher;
+    hasher.update(block);
+    StringRef hash = hasher.final();
+    assert(hash.size() == hashSize);
+    memcpy(hashes, hash.data(), hashSize);
+    code += blockSize;
+    hashes += hashSize;
+  }
+#if defined(__APPLE__)
+  // This is macOS-specific work-around and makes no sense for any
+  // other host OS. See https://openradar.appspot.com/FB8914231
+  //
+  // The macOS kernel maintains a signature-verification cache to
+  // quickly validate applications at time of execve(2).  The trouble
+  // is that for the kernel creates the cache entry at the time of the
+  // mmap(2) call, before we have a chance to write either the code to
+  // sign or the signature header+hashes.  The fix is to invalidate
+  // all cached data associated with the output file, thus discarding
+  // the bogus prematurely-cached signature.
+  msync(buf, fileOff + getSize(), MS_INVALIDATE);
+#endif
 }
 
 void CodeSignatureSection::writeTo(uint8_t *buf) const {
-  // The entire code section including header is written
-  // in CodeSignatureSection::writeHashes above.
-}
-
-void CodeSignatureSection::finalize() {
+  uint32_t signatureSize = static_cast<uint32_t>(getSize());
+  auto *superBlob = reinterpret_cast<CS_SuperBlob *>(buf);
+  write32be(&superBlob->magic, CSMAGIC_EMBEDDED_SIGNATURE);
+  write32be(&superBlob->length, signatureSize);
+  write32be(&superBlob->count, 1);
+  auto *blobIndex = reinterpret_cast<CS_BlobIndex *>(&superBlob[1]);
+  write32be(&blobIndex->type, CSSLOT_CODEDIRECTORY);
+  write32be(&blobIndex->offset, blobHeadersSize);
+  auto *codeDirectory =
+      reinterpret_cast<CS_CodeDirectory *>(buf + blobHeadersSize);
+  write32be(&codeDirectory->magic, CSMAGIC_CODEDIRECTORY);
+  write32be(&codeDirectory->length, signatureSize - blobHeadersSize);
+  write32be(&codeDirectory->version, CS_SUPPORTSEXECSEG);
+  write32be(&codeDirectory->flags, CS_ADHOC | CS_LINKER_SIGNED);
+  write32be(&codeDirectory->hashOffset,
+            sizeof(CS_CodeDirectory) + fileName.size() + fileNamePad);
+  write32be(&codeDirectory->identOffset, sizeof(CS_CodeDirectory));
+  codeDirectory->nSpecialSlots = 0;
+  write32be(&codeDirectory->nCodeSlots, getBlockCount());
+  write32be(&codeDirectory->codeLimit, fileOff);
+  codeDirectory->hashSize = static_cast<uint8_t>(hashSize);
+  codeDirectory->hashType = kSecCodeSignatureHashSHA256;
+  codeDirectory->platform = 0;
+  codeDirectory->pageSize = blockSizeShift;
+  codeDirectory->spare2 = 0;
+  codeDirectory->scatterOffset = 0;
+  codeDirectory->teamOffset = 0;
+  codeDirectory->spare3 = 0;
+  codeDirectory->codeLimit64 = 0;
   OutputSegment *textSeg = getOrCreateOutputSegment(segment_names::text);
-  // NOTE: ld64 seems to also use outputFile instead of finalOutput
-  sectionBuilder = std::make_unique<object::CodeSignatureSection>(
-      fileOff, config->outputFile, config->outputType, textSeg->fileOff,
-      textSeg->fileSize);
+  write64be(&codeDirectory->execSegBase, textSeg->fileOff);
+  write64be(&codeDirectory->execSegLimit, textSeg->fileSize);
+  write64be(&codeDirectory->execSegFlags,
+            config->outputType == MH_EXECUTE ? CS_EXECSEG_MAIN_BINARY : 0);
+  auto *id = reinterpret_cast<char *>(&codeDirectory[1]);
+  memcpy(id, fileName.begin(), fileName.size());
+  memset(id + fileName.size(), 0, fileNamePad);
 }
 
 BitcodeBundleSection::BitcodeBundleSection()

diff  --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 5c1f95b543f75..bbb7adc37cb35 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -21,7 +21,6 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/MC/StringTableBuilder.h"
-#include "llvm/Object/MachO.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -477,15 +476,24 @@ class IndirectSymtabSection final : public LinkEditSection {
 // The code signature comes at the very end of the linked output file.
 class CodeSignatureSection final : public LinkEditSection {
 public:
+  static constexpr uint8_t blockSizeShift = 12;
+  static constexpr size_t blockSize = (1 << blockSizeShift); // 4 KiB
+  static constexpr size_t hashSize = 256 / 8;
+  static constexpr size_t blobHeadersSize = llvm::alignTo<8>(
+      sizeof(llvm::MachO::CS_SuperBlob) + sizeof(llvm::MachO::CS_BlobIndex));
+  static constexpr uint32_t fixedHeadersSize =
+      blobHeadersSize + sizeof(llvm::MachO::CS_CodeDirectory);
+
+  uint32_t fileNamePad = 0;
+  uint32_t allHeadersSize = 0;
+  StringRef fileName;
+
   CodeSignatureSection();
   uint64_t getRawSize() const override;
   bool isNeeded() const override { return true; }
   void writeTo(uint8_t *buf) const override;
+  uint32_t getBlockCount() const;
   void writeHashes(uint8_t *buf) const;
-  void finalize() override;
-
-private:
-  std::unique_ptr<llvm::object::CodeSignatureSection> sectionBuilder;
 };
 
 class BitcodeBundleSection final : public SyntheticSection {

diff  --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index 78b0955cfdda1..d2ad12e98deb8 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -733,44 +733,6 @@ inline const ObjectFile *DiceRef::getObjectFile() const {
   return OwningObject;
 }
 
-class CodeSignatureSection {
-public:
-  uint32_t getRawSize() const;
-  uint32_t getSize() const;
-
-  static constexpr int Align = 16;
-  static constexpr uint8_t BlockSizeShift = 12;
-  static constexpr size_t BlockSize = (1 << BlockSizeShift); // 4 KiB
-  static constexpr size_t HashSize = 256 / 8;
-  static constexpr size_t BlobHeadersSize =
-      alignTo<8>(sizeof(MachO::CS_SuperBlob) + sizeof(MachO::CS_BlobIndex));
-  static constexpr uint32_t FixedHeadersSize =
-      BlobHeadersSize + sizeof(MachO::CS_CodeDirectory);
-
-  CodeSignatureSection(uint64_t FileOff, StringRef OutputFilePath,
-                       MachO::HeaderFileType OutputFileType,
-                       uint64_t TextSegmentFileOff,
-                       uint64_t TextSegmentFileSize);
-
-  void write(uint8_t *Buf) const;
-
-private:
-  uint32_t getAllHeadersSize() const;
-  uint32_t getBlockCount() const;
-  uint32_t getFileNamePad() const;
-
-  StringRef stripOutputFilePath(const StringRef OutputFilePath);
-
-  // FileOff is the offset relative to the start of the file
-  // used to access the start of code signature section
-  // in __LINKEDIT segment
-  uint64_t FileOff;
-  StringRef OutputFileName;
-  MachO::HeaderFileType OutputFileType;
-  uint64_t TextSegmentFileOff;
-  uint64_t TextSegmentFileSize;
-};
-
 } // end namespace object
 } // end namespace llvm
 

diff  --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt
index 1ebf967f72f8c..d5f123576fe20 100644
--- a/llvm/lib/Object/CMakeLists.txt
+++ b/llvm/lib/Object/CMakeLists.txt
@@ -2,7 +2,6 @@ add_llvm_component_library(LLVMObject
   Archive.cpp
   ArchiveWriter.cpp
   Binary.cpp
-  CodeSignatureSection.cpp
   COFFImportFile.cpp
   COFFModuleDefinition.cpp
   COFFObjectFile.cpp

diff  --git a/llvm/lib/Object/CodeSignatureSection.cpp b/llvm/lib/Object/CodeSignatureSection.cpp
deleted file mode 100644
index 9f6e3573eab29..0000000000000
--- a/llvm/lib/Object/CodeSignatureSection.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-//===- CodeSignatureSection.cpp - CodeSignatureSection class definition ---===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CodeSignatureSection class
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/SHA256.h"
-#include <cassert>
-
-#if defined(__APPLE__)
-#include <sys/mman.h>
-#endif
-
-using namespace llvm;
-using namespace object;
-using namespace support::endian;
-
-static_assert((CodeSignatureSection::BlobHeadersSize % 8) == 0, "");
-static_assert((CodeSignatureSection::FixedHeadersSize % 8) == 0, "");
-
-CodeSignatureSection::CodeSignatureSection(uint64_t FileOff,
-                                           StringRef OutputFilePath,
-                                           MachO::HeaderFileType OutputFileType,
-                                           uint64_t TextSegmentFileOff,
-                                           uint64_t TextSegmentFileSize)
-    : FileOff{FileOff}, OutputFileName{stripOutputFilePath(OutputFilePath)},
-      OutputFileType{OutputFileType}, TextSegmentFileOff{TextSegmentFileOff},
-      TextSegmentFileSize{TextSegmentFileSize} {}
-
-StringRef
-CodeSignatureSection::stripOutputFilePath(const StringRef OutputFilePath) {
-  const size_t LastSlashIndex = OutputFilePath.rfind("/");
-  if (LastSlashIndex == std::string::npos)
-    return OutputFilePath;
-
-  return OutputFilePath.drop_front(LastSlashIndex + 1);
-}
-
-uint32_t CodeSignatureSection::getAllHeadersSize() const {
-  return alignTo<Align>(FixedHeadersSize + OutputFileName.size() + 1);
-}
-
-uint32_t CodeSignatureSection::getBlockCount() const {
-  return (FileOff + BlockSize - 1) / BlockSize;
-}
-
-uint32_t CodeSignatureSection::getFileNamePad() const {
-  return getAllHeadersSize() - FixedHeadersSize - OutputFileName.size();
-}
-
-uint32_t CodeSignatureSection::getRawSize() const {
-  return getAllHeadersSize() + getBlockCount() * HashSize;
-}
-
-uint32_t CodeSignatureSection::getSize() const {
-  return alignTo<Align>(getRawSize());
-}
-
-void CodeSignatureSection::write(uint8_t *Buf) const {
-  const uint32_t AllHeadersSize = getAllHeadersSize();
-  const uint32_t BlockCount = getBlockCount();
-  const uint32_t FileNamePad = getFileNamePad();
-  const uint32_t Size = getSize();
-
-  uint8_t *Code = Buf;
-  uint8_t *CodeEnd = Buf + FileOff;
-  uint8_t *Hashes = CodeEnd + AllHeadersSize;
-
-  // Write code section header.
-  auto *SuperBlob = reinterpret_cast<MachO::CS_SuperBlob *>(CodeEnd);
-  write32be(&SuperBlob->magic, MachO::CSMAGIC_EMBEDDED_SIGNATURE);
-  write32be(&SuperBlob->length, Size);
-  write32be(&SuperBlob->count, 1);
-  auto *BlobIndex = reinterpret_cast<MachO::CS_BlobIndex *>(&SuperBlob[1]);
-  write32be(&BlobIndex->type, MachO::CSSLOT_CODEDIRECTORY);
-  write32be(&BlobIndex->offset, BlobHeadersSize);
-  auto *CodeDirectory =
-      reinterpret_cast<MachO::CS_CodeDirectory *>(CodeEnd + BlobHeadersSize);
-  write32be(&CodeDirectory->magic, MachO::CSMAGIC_CODEDIRECTORY);
-  write32be(&CodeDirectory->length, Size - BlobHeadersSize);
-  write32be(&CodeDirectory->version, MachO::CS_SUPPORTSEXECSEG);
-  write32be(&CodeDirectory->flags, MachO::CS_ADHOC | MachO::CS_LINKER_SIGNED);
-  write32be(&CodeDirectory->hashOffset, sizeof(MachO::CS_CodeDirectory) +
-                                            OutputFileName.size() +
-                                            FileNamePad);
-  write32be(&CodeDirectory->identOffset, sizeof(MachO::CS_CodeDirectory));
-  CodeDirectory->nSpecialSlots = 0;
-  write32be(&CodeDirectory->nCodeSlots, BlockCount);
-  write32be(&CodeDirectory->codeLimit, FileOff);
-  CodeDirectory->hashSize = static_cast<uint8_t>(HashSize);
-  CodeDirectory->hashType = MachO::kSecCodeSignatureHashSHA256;
-  CodeDirectory->platform = 0;
-  CodeDirectory->pageSize = BlockSizeShift;
-  CodeDirectory->spare2 = 0;
-  CodeDirectory->scatterOffset = 0;
-  CodeDirectory->teamOffset = 0;
-  CodeDirectory->spare3 = 0;
-  CodeDirectory->codeLimit64 = 0;
-  write64be(&CodeDirectory->execSegBase, TextSegmentFileOff);
-  write64be(&CodeDirectory->execSegLimit, TextSegmentFileSize);
-  write64be(&CodeDirectory->execSegFlags, OutputFileType == MachO::MH_EXECUTE
-                                              ? MachO::CS_EXECSEG_MAIN_BINARY
-                                              : 0);
-  auto *Id = reinterpret_cast<char *>(&CodeDirectory[1]);
-  memcpy(Id, OutputFileName.begin(), OutputFileName.size());
-  memset(Id + OutputFileName.size(), 0, FileNamePad);
-
-  // Write code section signature.
-  while (Code < CodeEnd) {
-    StringRef Block(reinterpret_cast<char *>(Code),
-                    std::min(CodeEnd - Code, static_cast<ssize_t>(BlockSize)));
-    SHA256 Hasher;
-    Hasher.update(Block);
-    StringRef Hash = Hasher.final();
-    assert(Hash.size() == HashSize);
-    memcpy(Hashes, Hash.data(), HashSize);
-    Code += BlockSize;
-    Hashes += HashSize;
-  }
-#if defined(__APPLE__)
-  // This is macOS-specific work-around and makes no sense for any
-  // other host OS. See https://openradar.appspot.com/FB8914231
-  //
-  // The macOS kernel maintains a signature-verification cache to
-  // quickly validate applications at time of execve(2).  The trouble
-  // is that for the kernel creates the cache entry at the time of the
-  // mmap(2) call, before we have a chance to write either the code to
-  // sign or the signature header+hashes.  The fix is to invalidate
-  // all cached data associated with the output file, thus discarding
-  // the bogus prematurely-cached signature.
-  msync(Buf, FileOff + Size, MS_INVALIDATE);
-#endif
-}


        


More information about the llvm-commits mailing list