[PATCH] D157300: [lld-macho]Rework error-checking in peeking at first-member in archive to avoid segfault.

Vy Nguyen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 7 10:44:58 PDT 2023


oontvoo created this revision.
oontvoo added a reviewer: MaskRay.
Herald added projects: lld-macho, All.
Herald added a reviewer: lld-macho.
oontvoo requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Details:
calling getMemoryBufferRef() on an empty archive can sometimes trigger segfault so the code should check before calling this.
this seems like a bug in the Archive API but that can be fixed separately.

P.S: follow up to D156468 <https://reviews.llvm.org/D156468>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157300

Files:
  lld/MachO/InputFiles.cpp


Index: lld/MachO/InputFiles.cpp
===================================================================
--- lld/MachO/InputFiles.cpp
+++ lld/MachO/InputFiles.cpp
@@ -2107,27 +2107,31 @@
 
 void ArchiveFile::addLazySymbols() {
   Error err = Error::success();
-  Expected<MemoryBufferRef> mbOrErr =
-      this->file->child_begin(err)->getMemoryBufferRef();
+  auto child = file->child_begin(err);
 
   // Ignore the I/O error here - will be reported later.
-  if (!mbOrErr) {
-    llvm::consumeError(mbOrErr.takeError());
-  } else if (!err) {
-    if (identify_magic(mbOrErr->getBuffer()) == file_magic::macho_object) {
-      if (target->wordSize == 8)
-        compatArch = compatWithTargetArch(
-            this, reinterpret_cast<const LP64::mach_header *>(
-                      mbOrErr->getBufferStart()));
-      else
-        compatArch = compatWithTargetArch(
-            this, reinterpret_cast<const ILP32::mach_header *>(
-                      mbOrErr->getBufferStart()));
-
-      if (!compatArch)
-        return;
+  // Also avoid calling getMemoryBUfferRef() on zero-symbol archive
+  // since that crashes.
+  if (!err && file->getNumberOfSymbols() > 0) {
+    Expected<MemoryBufferRef> mbOrErr = child->getMemoryBufferRef();
+    if (!mbOrErr) {
+      llvm::consumeError(mbOrErr.takeError());
+    } else {
+      if (identify_magic(mbOrErr->getBuffer()) == file_magic::macho_object) {
+        if (target->wordSize == 8)
+          compatArch = compatWithTargetArch(
+              this, reinterpret_cast<const LP64::mach_header *>(
+                        mbOrErr->getBufferStart()));
+        else
+          compatArch = compatWithTargetArch(
+              this, reinterpret_cast<const ILP32::mach_header *>(
+                        mbOrErr->getBufferStart()));
+        if (!compatArch)
+          return;
+      }
     }
   }
+
   for (const object::Archive::Symbol &sym : file->symbols())
     symtab->addLazyArchive(sym.getName(), this, sym);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157300.547845.patch
Type: text/x-patch
Size: 1974 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230807/28b37f38/attachment.bin>


More information about the llvm-commits mailing list