[PATCH] D155485: Retain all jump table range checks when using BTI.

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 26 02:19:28 PDT 2023


peter.smith added a comment.

In D155485#4534309 <https://reviews.llvm.org/D155485#4534309>, @MaskRay wrote:

> In D155485#4506823 <https://reviews.llvm.org/D155485#4506823>, @peter.smith wrote:
>
>> I can confirm that this is Arm's preferred way of fixing this. The alternative is to always use a BTI setting indirect branch, but this requires adding `BTI j` in front of every valid target of the branch, which bloats code-size and leaves more targets for an attacker to indirectly jump to.
>
> I see that the AArch64 equivalent (by changing `llvm.arm.space` to `llvm.aarch64.space`) has `bti j` in front of every valid target of the branch, therefore bloating code size.
> But how does this leave more targets for an attacker to indirectly jump to? Do you mean that these `bti j` can be the target of a malicious indirect jump from elsewhere?

Yes. The theory is that if the attacker finds some vulnerability outside of the function, they can jump to the start of each case statement, which increases the number of gadgets in the program, whether those can be usefully exploited or not will depend on the program. It also has the side-effect of increasing code-size.

> However, isn't this as unsafe as jumping to the default basic block (in this test case, the end of the function, after the RET) for an out-of-range branch value in the current `switch` instruction?

In the AArch32 case the MOV PC, <REG> instruction can land anywhere, not just at the start of a BTI instruction. On AArch64 the BX <reg> instruction is at least constrained to a BTI compatible landing pad.

Hope I've understood the question well enough to answer there.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155485/new/

https://reviews.llvm.org/D155485



More information about the llvm-commits mailing list