From 918787584e8faf76267ba20d9ce1853d453ded03 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Fri, 15 Jul 2022 10:40:20 +0200 Subject: [PATCH] Avoid UAF in WinCOFFObjectWriter with weak symbols. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Differential Revision: https://reviews.llvm.org/D129840 --- llvm/lib/MC/WinCOFFObjectWriter.cpp | 1 + llvm/test/MC/COFF/weak-uaf.ll | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 llvm/test/MC/COFF/weak-uaf.ll diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 35f1ba3364594e..e2de61cd02640d 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -172,6 +172,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 00000000000000..d0df144358c953 --- /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 +}