Skip to content

Commit 9187875

Browse files
maleadtvchuravy
authored andcommitted
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 Differential Revision: https://reviews.llvm.org/D129840
1 parent 0689fbf commit 9187875

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
@@ -172,6 +172,7 @@ class WinCOFFObjectWriter : public MCObjectWriter {
172172
Strings.clear();
173173
SectionMap.clear();
174174
SymbolMap.clear();
175+
WeakDefaults.clear();
175176
MCObjectWriter::reset();
176177
}
177178

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)