Skip to content

Commit c71d778

Browse files
maleadtmstorsjo
authored andcommitted
[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: JuliaLang/julia#45649 Reviewed By: mstorsjo Differential Revision: https://reviews.llvm.org/D129840
1 parent 1cb7416 commit c71d778

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

llvm/lib/MC/WinCOFFObjectWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class WinCOFFObjectWriter : public MCObjectWriter {
169169
Strings.clear();
170170
SectionMap.clear();
171171
SymbolMap.clear();
172+
WeakDefaults.clear();
172173
MCObjectWriter::reset();
173174
}
174175

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llc --compile-twice -mtriple=x86_64-pc-win32 -filetype=obj < %s
2+
3+
; UAF when re-using the MCObjectWriter. does not leak into the output,
4+
; but should be detectable with --compile-twice under ASAN or so.
5+
6+
define weak void @foo() nounwind {
7+
ret void
8+
}
9+
10+
define weak void @bar() nounwind {
11+
ret void
12+
}

0 commit comments

Comments
 (0)