[PATCH] D120073: [LLD] Fix for race condition.

Alexander Yermolovich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 17 10:04:58 PST 2022


ayermolo created this revision.
Herald added subscribers: hoy, modimo, wenlei, arichardson, emaste.
Herald added a reviewer: MaskRay.
ayermolo requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

There is a potential race condition when getErrPlace is invoked in multi
threaded context and Out::bufferStart is not used.
Thread A and B pass the check in InputSectionBase:data(). Thread A decompresses
sets uncompressedSize to -1. Thread B now uses that value and this leads to zlib
erroring out.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120073

Files:
  lld/ELF/InputSection.cpp
  lld/ELF/InputSection.h


Index: lld/ELF/InputSection.h
===================================================================
--- lld/ELF/InputSection.h
+++ lld/ELF/InputSection.h
@@ -157,8 +157,7 @@
   }
 
   ArrayRef<uint8_t> data() const {
-    if (uncompressedSize >= 0)
-      uncompress();
+    uncompress();
     return rawData;
   }
 
Index: lld/ELF/InputSection.cpp
===================================================================
--- lld/ELF/InputSection.cpp
+++ lld/ELF/InputSection.cpp
@@ -118,17 +118,24 @@
 void InputSectionBase::uncompress() const {
   size_t size = uncompressedSize;
   char *uncompressedBuf;
+  static std::mutex mu;
   {
-    static std::mutex mu;
     std::lock_guard<std::mutex> lock(mu);
+    if (uncompressedSize <= 0)
+      return;
     uncompressedBuf = bAlloc().Allocate<char>(size);
   }
 
   if (Error e = zlib::uncompress(toStringRef(rawData), uncompressedBuf, size))
     fatal(toString(this) +
           ": uncompress failed: " + llvm::toString(std::move(e)));
-  rawData = makeArrayRef((uint8_t *)uncompressedBuf, size);
-  uncompressedSize = -1;
+
+  {
+    std::lock_guard<std::mutex> lock(mu);
+    if (uncompressedSize <= 0)
+      rawData = makeArrayRef((uint8_t *)uncompressedBuf, size);
+    uncompressedSize = -1;
+  }
 }
 
 template <class ELFT> RelsOrRelas<ELFT> InputSectionBase::relsOrRelas() const {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120073.409704.patch
Type: text/x-patch
Size: 1338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220217/c6a0ff66/attachment.bin>


More information about the llvm-commits mailing list