[llvm] c71d778 - [MC] Avoid UAF in WinCOFFObjectWriter with weak symbols.

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 16 03:26:07 PDT 2022


Author: Tim Besard
Date: 2022-07-16T13:24:08+03:00
New Revision: c71d77876f52eae52312ce130b5f0c1472b0699b

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

LOG: [MC] Avoid UAF in WinCOFFObjectWriter with weak symbols.

When using weak symbols, the WinCOFFObjectWriter keeps a list (`WeakDefaults`)
that's used to make names unique. This list should be reset when the object
writer is reset, because otherwise reuse of the object writer can result in
freed symbols being accessed. With some added output, this becomes clear when
using `llc` in `--run-twice` mode:

```
$ ./llc --compile-twice -mtriple=x86_64-pc-win32 trivial.ll -filetype=obj

DefineSymbol::WeakDefaults
 - .weak.foo.default
 - .weak.bar.default

DefineSymbol::WeakDefaults
 - .weak.foo.default
 - áÑJij⌂  p§┼Ø┐☺
 - .debug_macinfo.dw
 - .weak.bar.default
```

This does not seem to leak into the output object file though, so I couldn't
come up with a test. I added one that just does `--run-twice` (and verified
that it does access freed memory), which should result in detecting the
invalid memory accesses when running under ASAN.

Observed in a Julia PR where we started using weak symbols:
https://github.com/JuliaLang/julia/pull/45649

Reviewed By: mstorsjo

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

Added: 
    llvm/test/MC/COFF/weak-uaf.ll

Modified: 
    llvm/lib/MC/WinCOFFObjectWriter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 33e496b7a8645..809ac37c3442f 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -169,6 +169,7 @@ class WinCOFFObjectWriter : public MCObjectWriter {
     Strings.clear();
     SectionMap.clear();
     SymbolMap.clear();
+    WeakDefaults.clear();
     MCObjectWriter::reset();
   }
 

diff  --git a/llvm/test/MC/COFF/weak-uaf.ll b/llvm/test/MC/COFF/weak-uaf.ll
new file mode 100644
index 0000000000000..d0df144358c95
--- /dev/null
+++ b/llvm/test/MC/COFF/weak-uaf.ll
@@ -0,0 +1,12 @@
+; RUN: llc --compile-twice -mtriple=x86_64-pc-win32 -filetype=obj < %s
+
+; UAF when re-using the MCObjectWriter. does not leak into the output,
+; but should be detectable with --compile-twice under ASAN or so.
+
+define weak void @foo() nounwind {
+  ret void
+}
+
+define weak void @bar() nounwind {
+  ret void
+}


        


More information about the llvm-commits mailing list