Skip to content

Commit

Permalink
Avoid UAF in WinCOFFObjectWriter with weak symbols.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
maleadt authored and vchuravy committed Aug 23, 2022
1 parent 0689fbf commit 9187875
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
1 change: 1 addition & 0 deletions llvm/lib/MC/WinCOFFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class WinCOFFObjectWriter : public MCObjectWriter {
Strings.clear();
SectionMap.clear();
SymbolMap.clear();
WeakDefaults.clear();
MCObjectWriter::reset();
}

Expand Down
12 changes: 12 additions & 0 deletions llvm/test/MC/COFF/weak-uaf.ll
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 9187875

Please sign in to comment.