I've been working this all morning, but have to step out for a bit now.
This is the short short version of what I have found so far:
- This affects all stack protector values on aarch64, not just
-stack-protector 2. It is easier to trigger with 2 because it maps to
-fstack-protector-strong, which inserts more stack protectors.
- Passing -O2 makes it work.
- We probably haven't noticed this before because we compile everything
with -O2 by default.
- This is definitely a llvm8 thing - it worked on llvm7.
- insertSSPDeclarations() is supposed to only be used when
getIRStackGuard() returns nullptr, so the existing behaviour in
StackProtector and TargetLowering is correct.
- The real problem is that we are in the code path to lower the
LOAD_STACK_GUARD pseudo instruction, which we do not support, and
which assumes the SDag SSP, which we should be explicitly not using
because we return something in getIRStackGuard().
I will have some more later.
Todd
On Sat, Jul 06, 2019 at 06:20:46PM -0600, Theo de Raadt wrote:
> + mortimer@
>
> Krystian Lewandowski <[email protected]> wrote:
>
> > Based on information from Dimitry Andric:
> > https://bugs.llvm.org/show_bug.cgi?id=42478
> > - it does happen only for -triple aarch64-unknown-openbsd
> > - with -stack-protector 2
> > I tried to find a reason for this behaviour. Please note I have no
> > knowledge
> > about LLVM internals, dont trust me, double check.
> >
> > I'll point to OpenBSD (master branch) github links, I hope its fine with
> > you.
> >
> > 1. So the crash is caused directly by:
> > https://github.com/openbsd/src/blob/master/gnu/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp#L1500
> > where getValue() is called on NULL pointer.
> >
> > 2. I think it is caused by Global being NULL here:
> > https://github.com/openbsd/src/blob/master/gnu/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp#L766
> > It should be returned from provided module as __stack_chk_guard function.
> > https://github.com/openbsd/src/blob/master/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp#L1658
> >
> > 3. This "__stack_chk_guard" function should be registered here:
> > https://github.com/openbsd/src/blob/master/gnu/llvm/lib/CodeGen/StackProtector.cpp#L341
> > by
> > insertSSPDeclarations() call but this piece of code is never executed
> > because
> > getStackGuard() returns earlier - getIRStackGuard() returns non-NULL value:
> > https://github.com/openbsd/src/blob/master/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp#L1635
> >
> > Im not sure which one is valid:
> > a. with TargetLoweringBase::getIRStackGuard() returning non-NULL value,
> > TargetLoweringBase::getSDagStackGuard() should never be called by
> > IRTranslator::getStackGuard() and this flow should be handled in a
> > different manner
> > b. or insertSSPDeclarations() should be called in
> > StackProtector::getStackGuard()
> > in both cases
> >
> > I was able to get rid of crash by the diff below (b. case).
> >
> > --
> > Krystian
> >
> > Index: StackProtector.cpp
> > ===================================================================
> > RCS file: /cvs/src/gnu/llvm/lib/CodeGen/StackProtector.cpp,v
> > retrieving revision 1.8
> > diff -u -p -r1.8 StackProtector.cpp
> > --- StackProtector.cpp 23 Jun 2019 22:05:12 -0000 1.8
> > +++ StackProtector.cpp 5 Jul 2019 20:41:17 -0000
> > @@ -322,8 +322,10 @@ bool StackProtector::RequiresStackProtec
> > static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
> > IRBuilder<> &B,
> > bool *SupportsSelectionDAGSP = nullptr) {
> > - if (Value *Guard = TLI->getIRStackGuard(B))
> > + if (Value *Guard = TLI->getIRStackGuard(B)) {
> > + TLI->insertSSPDeclarations(*M);
> > return B.CreateLoad(Guard, true, "StackGuard");
> > + }
> >
> > // Use SelectionDAG SSP handling, since there isn't an IR guard.
> > //
> >
> > > Wiadomość napisana przez Patrick Wildt <[email protected]> w dniu
> > > 05.07.2019, o godz. 09:02:
> > >
> > > On Tue, Jul 02, 2019 at 02:07:22PM +0200, Krystian Lewandowski wrote:
> > >>
> > >>> Wiadomość napisana przez Krystian Lewandowski <[email protected]> w
> > >>> dniu 01.07.2019, o godz. 21:50:
> > >>>
> > >>> I thought it would be a good idea to rebuild cross-tools because of
> > >>> LLVM version bump
> > >>> but - with recent src - I'm unable to do so:
> > >>> $ doas make -f Makefile.cross TARGET=${target} CROSSDIR="${destdir}"
> > >>> cross-tools
> > >>> fails with:
> > >>> aarch64-unknown-openbsd6: error: unable to execute command:
> > >>> Segmentation fault
> > >>> (core dumped)
> > >>>
> > >>> With updated /etc/mk.conf:
> > >>> DEBUG=-gline-tables-only
> > >>> (I think it’s unused for clang but disables stripping during
> > >>> installation?)
> > >>>
> > >>> and src/gnu/usr.bin/clang/Makefile.inc:
> > >>> CPPFLAGS+= -DNDEBUG -gline-tables-only
> > >>> (I think it’s similar to what cmake RelWithDebugInfo does.)
> > >>>
> > >>> I was eventually able to get debug symbols. More details in attached
> > >>> files.
> > >>> I reproduced this crash on other machine.
> > >>>
> > >>> Is this something for LLVM team to look at?
> > >>>
> > >>> If anyone would like to give it a quick try, then please just follow
> > >>> „Setup” section from:
> > >>> https://github.com/elewarr/openbsd-arm64-src-dev
> > >>>
> > >>> --
> > >>> Krystian
> > >>>
> > >>> <cxa_demangle-042165.cpp.tgz><crash_log.txt><cxa_demangle-042165.sh><stack.txt>
> > >>>
> > >>>
> > >>
> > >> Reported to LLVM: https://bugs.llvm.org/show_bug.cgi?id=42478
> > >>
> > >> --
> > >> Krystian
> > >>
> > >
> > > I see this as well, what a bummer. What I can see is that if I use my
> > > make wrapper to compile the files, and -j1, it doesn't crash. I wonder
> > > what the big difference is.
> > >
> >