Skip to content

llvm-objdump: corrupt ELF file can crash llvm-objdump in printSymbolVersionDefinition() #86611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emaste opened this issue Mar 26, 2024 · 5 comments · May be fixed by #115284
Closed

llvm-objdump: corrupt ELF file can crash llvm-objdump in printSymbolVersionDefinition() #86611

emaste opened this issue Mar 26, 2024 · 5 comments · May be fixed by #115284

Comments

@emaste
Copy link
Member

emaste commented Mar 26, 2024

Reported against FreeBSD in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277861, with ELF reproducer attached

# objdump --version
LLVM (http://llvm.org/):
  LLVM version 17.0.6
  Optimized build with assertions.
...
# objdump -p objdump2a.exe

objdump2a.exe:  file format elf32-lanai

Program Header:
objdump: warning: 'objdump2a.exe': section [index 7] has invalid sh_entsize: expected 8, but got 5

Version definitions:
1 0x00 0x7650bc00 PLEASE submit a bug report to https://bugs.freebsd.org/submit/ and include the crash backtrace.
Stack dump:
0.      Program arguments: objdump -p objdump2a.exe
 #0 0x0000000001230c41 PrintStackTrace /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:602:13
 #1 0x000000000122f0b5 RunSignalHandlers /usr/src/contrib/llvm-project/llvm/lib/Support/Signals.cpp:105:18
 #2 0x0000000001231365 SignalHandler /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
 #3 0x00000008255ae5ff handle_signal /usr/src/lib/libthr/thread/thr_sig.c:0:3
 #4 0x00000008255adbbb thr_sighandler /usr/src/lib/libthr/thread/thr_sig.c:244:1
 #5 0x00000008223cd2d3 ([vdso]+0x2d3)
 #6 0x0000000000de60d7 read<unsigned int, 1UL> /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:66:3
 #7 0x0000000000de60d7 read<unsigned int, (llvm::support::endianness)1, 1UL> /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:77:10
 #8 0x0000000000de60d7 operator unsigned int /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:216:12
 #9 0x0000000000de60d7 printSymbolVersionDefinition<llvm::object::ELFType<(llvm::support::endianness)1, false> > /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:398:45
#10 0x0000000000de60d7 printSymbolVersion /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:425:7
#11 0x0000000000de60d7 printPrivateHeaders /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:432:3
#12 0x0000000000e6a13c dumpObject /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:2815:7
#13 0x0000000000e654b0 dumpInput /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:0:5
#14 0x0000000000e654b0 for_each<std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > *>, void (*)(llvm::StringRef)> /usr/obj/usr/src/amd64.amd64/tmp/usr/include/c++/v1/__algorithm/for_each.h:26:5
#15 0x0000000000e654b0 for_each<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > &, void (*)(llvm::StringRef)> /usr/src/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h:1731:10
#16 0x0000000000e654b0 main /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:3248:3
#17 0x0000000828d4d0aa __libc_start1 /usr/src/lib/libc/csu/libc_start1.c:157:2
Segmentation fault (core dumped)
@llvmbot
Copy link
Member

llvmbot commented Mar 26, 2024

@llvm/issue-subscribers-tools-llvm-objdump

Author: Ed Maste (emaste)

Reported against FreeBSD in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277861, with ELF reproducer attached
# objdump --version
LLVM (http://llvm.org/):
  LLVM version 17.0.6
  Optimized build with assertions.
...
# objdump -p objdump2a.exe

objdump2a.exe:  file format elf32-lanai

Program Header:
objdump: warning: 'objdump2a.exe': section [index 7] has invalid sh_entsize: expected 8, but got 5

Version definitions:
1 0x00 0x7650bc00 PLEASE submit a bug report to https://bugs.freebsd.org/submit/ and include the crash backtrace.
Stack dump:
0.      Program arguments: objdump -p objdump2a.exe
 #<!-- -->0 0x0000000001230c41 PrintStackTrace /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:602:13
 #<!-- -->1 0x000000000122f0b5 RunSignalHandlers /usr/src/contrib/llvm-project/llvm/lib/Support/Signals.cpp:105:18
 #<!-- -->2 0x0000000001231365 SignalHandler /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
 #<!-- -->3 0x00000008255ae5ff handle_signal /usr/src/lib/libthr/thread/thr_sig.c:0:3
 #<!-- -->4 0x00000008255adbbb thr_sighandler /usr/src/lib/libthr/thread/thr_sig.c:244:1
 #<!-- -->5 0x00000008223cd2d3 ([vdso]+0x2d3)
 #<!-- -->6 0x0000000000de60d7 read&lt;unsigned int, 1UL&gt; /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:66:3
 #<!-- -->7 0x0000000000de60d7 read&lt;unsigned int, (llvm::support::endianness)1, 1UL&gt; /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:77:10
 #<!-- -->8 0x0000000000de60d7 operator unsigned int /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Endian.h:216:12
 #<!-- -->9 0x0000000000de60d7 printSymbolVersionDefinition&lt;llvm::object::ELFType&lt;(llvm::support::endianness)1, false&gt; &gt; /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:398:45
#<!-- -->10 0x0000000000de60d7 printSymbolVersion /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:425:7
#<!-- -->11 0x0000000000de60d7 printPrivateHeaders /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/ELFDump.cpp:432:3
#<!-- -->12 0x0000000000e6a13c dumpObject /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:2815:7
#<!-- -->13 0x0000000000e654b0 dumpInput /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:0:5
#<!-- -->14 0x0000000000e654b0 for_each&lt;std::__1::__wrap_iter&lt;std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; *&gt;, void (*)(llvm::StringRef)&gt; /usr/obj/usr/src/amd64.amd64/tmp/usr/include/c++/v1/__algorithm/for_each.h:26:5
#<!-- -->15 0x0000000000e654b0 for_each&lt;std::__1::vector&lt;std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt;, std::__1::allocator&lt;std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; &gt; &gt; &amp;, void (*)(llvm::StringRef)&gt; /usr/src/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h:1731:10
#<!-- -->16 0x0000000000e654b0 main /usr/src/contrib/llvm-project/llvm/tools/llvm-objdump/llvm-objdump.cpp:3248:3
#<!-- -->17 0x0000000828d4d0aa __libc_start1 /usr/src/lib/libc/csu/libc_start1.c:157:2
Segmentation fault (core dumped)

@jh7370
Copy link
Collaborator

jh7370 commented Mar 26, 2024

Does this reproduce with HEAD? There was very recent fix to the LLVM object library which might cover this case (though it is probably unrelated).

objdump: warning: 'objdump2a.exe': section [index 7] has invalid sh_entsize: expected 8, but got 5

I wouldn't be surprised if this is somehow related. I think it's going to be difficult to triage this without the actual object file though.

@antoniofrighetto
Copy link
Contributor

@jh7370, the object file is attached in the link within the report. I think something like the following should suffice:

--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -39,6 +39,9 @@ private:
   void printProgramHeaders();
   void printSymbolVersion();
   void printSymbolVersionDependency(const typename ELFT::Shdr &Sec);
+  void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
+                                    ArrayRef<uint8_t> Contents,
+                                    StringRef StrTab);
 };
 } // namespace
 
@@ -375,9 +378,9 @@ void ELFDumper<ELFT>::printSymbolVersionDependency(
 }
 
 template <class ELFT>
-static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
-                                         ArrayRef<uint8_t> Contents,
-                                         StringRef StrTab) {
+void ELFDumper<ELFT>::printSymbolVersionDefinition(
+    const typename ELFT::Shdr &Shdr, ArrayRef<uint8_t> Contents,
+    StringRef StrTab) {
   outs() << "\nVersion definitions:\n";
 
   const uint8_t *Buf = Contents.data();
@@ -393,6 +396,13 @@ static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
            << format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
 
     const uint8_t *BufAux = Buf + Verdef->vd_aux;
+    if (BufAux > Contents.end()) {
+      reportWarning("out-of-bound while parsing verdaux entries, corrupted "
+                    "verdef section",
+                    Obj.getFileName());
+      break;
+    }
+
     uint16_t VerdauxIndex = 0;
     while (BufAux) {

(Also taking a look at tests for previous fixes).

@MaskRay
Copy link
Member

MaskRay commented Oct 27, 2024

@antoniofrighetto This looks good. Can you upload a patch with a test?

antoniofrighetto added a commit to antoniofrighetto/llvm-project that referenced this issue Nov 7, 2024
…past size

Validate `vd_aux` while parsing `Elf_Verdef` structure.

Fixes: llvm#86611.
@antoniofrighetto
Copy link
Contributor

@antoniofrighetto This looks good. Can you upload a patch with a test?

Candidate patch: #115284 (sorry for replying back only now).

antoniofrighetto added a commit to antoniofrighetto/llvm-project that referenced this issue Nov 7, 2024
…past size

Validate `vd_aux` while parsing `Elf_Verdef` structure.

Fixes: llvm#86611.
antoniofrighetto added a commit to antoniofrighetto/llvm-project that referenced this issue Nov 8, 2024
…past size

Validate `vd_aux` while parsing `Elf_Verdef` structure.

Fixes: llvm#86611.
antoniofrighetto added a commit to antoniofrighetto/llvm-project that referenced this issue Nov 8, 2024
…past size

Validate `vd_aux` while parsing `Elf_Verdef` structure.

Fixes: llvm#86611.
@MaskRay MaskRay self-assigned this Feb 23, 2025
MaskRay added a commit that referenced this issue Feb 28, 2025
and fix crash when vd_aux is invalid (#86611).

vd_version, vd_flags, vd_ndx, and vd_cnt in Elf{32,64}_Verdef are
16-bit. Change VerDef to use uint16_t instead.

vda_name specifies a NUL-terminated string. Update getVersionDefinitions
to remove some `.c_str()`.

Pull Request: #128434
cheezeburglar pushed a commit to cheezeburglar/llvm-project that referenced this issue Feb 28, 2025
and fix crash when vd_aux is invalid (llvm#86611).

vd_version, vd_flags, vd_ndx, and vd_cnt in Elf{32,64}_Verdef are
16-bit. Change VerDef to use uint16_t instead.

vda_name specifies a NUL-terminated string. Update getVersionDefinitions
to remove some `.c_str()`.

Pull Request: llvm#128434
@MaskRay MaskRay closed this as completed May 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants