This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Harden indirect calls against SLS
ClosedPublic

Authored by kristof.beyls on Dec 2 2020, 1:55 AM.

Details

Summary

To make sure that no barrier gets placed on the architectural execution
path, each indirect call calling the function in register rN, it gets
transformed to a direct call to __llvm_slsblr_thunk_mode_rN.
mode is either arm or thumb, depending on the mode of where the indirect
call happens.

The llvm_slsblr_thunk_mode_rN thunk contains:

bx rN
<speculation barrier>

Therefore, the indirect call gets split into 2; one direct call and
one indirect jump.
This transformation results in not inserting a speculation barrier on
the architectural execution path.

The mitigation is off by default and can be enabled by the
harden-sls-blr subtarget feature.

As a linker is allowed to clobber r12 on function calls, the
above code transformation is not correct in case a linker does so.
Similarly, the transformation is not correct when register lr is used.
Avoiding r12/lr being used is done in a follow-on patch to make reviewing
this code easier.

Diff Detail

Event Timeline

kristof.beyls created this revision.Dec 2 2020, 1:55 AM
ostannard added inline comments.Dec 17 2020, 2:12 AM
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
694

Should this be above the return isV8EligibleForIT(&MI);? (same comment as D92395)

llvm/lib/Target/ARM/ARMSLSHardening.cpp
211

The addImm/addReg pair for the predicate can be done by .add(predOps(ARMCC::AL)), to be shorter and more self-documenting.

Updated patch based on review comments + rebased to ToT

kristof.beyls marked 2 inline comments as done.Dec 18 2020, 6:05 AM
This revision is now accepted and ready to land.Dec 18 2020, 6:19 AM
This revision was automatically updated to reflect the committed changes.