[lld] r315035 - [ELF] Don't crash when parsing a file with external version definition references

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 5 16:28:30 PDT 2017


Author: arichardson
Date: Thu Oct  5 16:28:29 2017
New Revision: 315035

URL: http://llvm.org/viewvc/llvm-project?rev=315035&view=rev
Log:
[ELF] Don't crash when parsing a file with external version definition references

Summary:
We were crashing when linking telnetd in FreeBSD because lld was emitting
corrupted output files for --norosegment. In this file the version index of some symbols
was set to 9 but lld only found 8 version definitions.

I am not sure how to create a minimal .so file that also exposes this behaviour so I just added the one that initially caused the error to Inputs/

This partially addresses https://bugs.llvm.org/show_bug.cgi?id=34705

Reviewers: ruiu, rafael, pcc, grimar

Reviewed By: ruiu

Subscribers: emaste, krytarowski

Tags: #lld

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

Added:
    lld/trunk/test/ELF/Inputs/corrupt-version-reference.so
    lld/trunk/test/ELF/corrupted-version-reference.s
Modified:
    lld/trunk/ELF/InputFiles.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=315035&r1=315034&r2=315035&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Oct  5 16:28:29 2017
@@ -775,9 +775,18 @@ template <class ELFT> void SharedFile<EL
     // Ignore local symbols.
     if (Versym && VersymIndex == VER_NDX_LOCAL)
       continue;
-
-    const Elf_Verdef *V =
-        VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex];
+    const Elf_Verdef *V = nullptr;
+    if (VersymIndex != VER_NDX_GLOBAL) {
+      if (VersymIndex >= Verdefs.size()) {
+        error("corrupt input file: version definition index " +
+              Twine(VersymIndex) + " for symbol " + Name +
+              " is greater than the maximum value " +
+              Twine(Verdefs.size() - 1) + "\n>>> symbol is defined in " +
+              toString(this));
+        continue;
+      }
+      V = Verdefs[VersymIndex];
+    }
 
     if (!Hidden)
       Symtab->addShared(Name, this, Sym, V);

Added: lld/trunk/test/ELF/Inputs/corrupt-version-reference.so
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/corrupt-version-reference.so?rev=315035&view=auto
==============================================================================
Binary files lld/trunk/test/ELF/Inputs/corrupt-version-reference.so (added) and lld/trunk/test/ELF/Inputs/corrupt-version-reference.so Thu Oct  5 16:28:29 2017 differ

Added: lld/trunk/test/ELF/corrupted-version-reference.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/corrupted-version-reference.s?rev=315035&view=auto
==============================================================================
--- lld/trunk/test/ELF/corrupted-version-reference.s (added)
+++ lld/trunk/test/ELF/corrupted-version-reference.s Thu Oct  5 16:28:29 2017
@@ -0,0 +1,10 @@
+# RUN: llvm-mc -triple=mips64-unknown-freebsd %s -filetype=obj -o %t.o
+# RUN: not ld.lld %t.o %S/Inputs/corrupt-version-reference.so -o %t.exe 2>&1 | FileCheck %s
+
+# CHECK: error: corrupt input file: version definition index 9 for symbol __cxa_finalize is greater than the maximum value 8
+# CHECK: >>> symbol is defined in {{.+}}/corrupt-version-reference.so
+
+.globl __start
+__start:
+    dla $a0, __cxa_finalize
+    nop




More information about the llvm-commits mailing list