arch/arm64: Add Branch Target Identification#421
arch/arm64: Add Branch Target Identification#421michpappas wants to merge 3 commits intounikraft:stagingfrom
Conversation
|
This PR depends on #369 |
6b53415 to
a3f9d02
Compare
a3f9d02 to
34fad74
Compare
plat/common/arm/psci_arm64.S
Outdated
| * int32_t smcc_psci_hvc_call(uint32_t, uint64_t, uint64_t, uint64_t); | ||
| */ | ||
| ENTRY(smcc_psci_hvc_call) | ||
| bti j |
There was a problem hiding this comment.
These instructions should be conditional to CONFIG_ARM64_FEAT_BTI. Otherwise will break the build for older compilers (i.e. gcc < 9).
There was a problem hiding this comment.
Good point. Actually this commit can be removed if PSCI calls are migrated to use the SMCCC API. @razvanvirtan, the BTI PR is scheduled for this release. Are you planning to include the PSCI change on this release too? If not I can push a update on this PR with @rene's suggestion.
There was a problem hiding this comment.
@michpappas I have created the PSCI change PR: #428
From what I see, this PR (the BTI one) is planed for the next release (0.9), so I think the PSCI one can be included in that release too.
There was a problem hiding this comment.
@razvanvirtan awesome, thanks a lot 🚀 I'll look at it this weekend. @razvand could we schedule this one for 0.9 too?
| @@ -0,0 +1,35 @@ | |||
| /* SPDX-License-Identifier: BSD-3-Clause */ | |||
| /* | |||
| * Copyright (c) YYYY, Copyright Holder. All rights reserved. | |||
There was a problem hiding this comment.
Actually this is intentional, because these headers are empty, so I think it doesn't make sense to grant the copyright to myself. The idea was that the copyright should be updated by whoever adds content. This is also what I do in the next commit where I add come content to arch/arm/arm64/include/uk/asm/compile.h and grant the copyright to myself.
| @@ -0,0 +1,35 @@ | |||
| /* SPDX-License-Identifier: BSD-3-Clause */ | |||
| /* | |||
| * Copyright (c) YYYY, Copyright Holder. All rights reserved. | |||
| @@ -0,0 +1,35 @@ | |||
| /* SPDX-License-Identifier: BSD-3-Clause */ | |||
| /* | |||
| * Copyright (c) YYYY, Copyright Holder. All rights reserved. | |||
34fad74 to
6acd153
Compare
|
Updated PR with a fix for checkpatch |
6acd153 to
1ddd550
Compare
|
Changes in this update:
|
|
@razvand, @razvanvirtan, @rene, @vladandrew this PR now depends on #428. I have also added this commit in this series to facilitate testing. Will rebase once #428 is merged. |
StefanJum
left a comment
There was a problem hiding this comment.
Looks good to me!
Should be rebased now that #428 is merged.
Reviewed-by: Stefan Jumarea stefanjumarea02@gmail.com
BTI (FEAT_BTI) is a hardware protection against JOP-like attacks. When BTI is enabled the compiler generates bti guard instructions, aka landing pads, on branch targets. On runtime, branches that do not land on a bti instruction trigger a Branch Target Exception. The expected branch type of an indirect jump is encoded in PSTATE.BTYPE. This further limits the scope of possible targets in BTI guarded pages. Pages guarded by BTI are marked by setting the GP field in their corresponding PTE. This is allows backwards compatibility, by disabling BTI on pages that contain non-BTI guarded code. Notice that BTI instructions on unguarded pages execute as NOP. FEAT_BTI is introduced as a mandatory feature in Armv8.5. As BTI is implemented in the Hint space, this feature is backwards compatible with systems based on older architecture revisions. This commit adds BTI support on arm64-based platforms through a new Kconfig option CONFIG_ARM64_FEAT_BTI. When enabled, the build system passes GCC the appropriate flags to enable BTI. It further updates default PTE attributes of executable pages are updated to set the GP attribute, when BTI is enabled. As GCC only generates BTI instructions for C code, platforms need to make sure that assembly functions that are called through indirect branching are updated with landing pads before BTI support is enabled. Signed-off-by: Michalis Pappas <mpappas@fastmail.fm>
Currently _libkvmplat_start() switches to the runtime stack via a trampoline before passing control to ukboot. This appears to be unnecessary and introduces complications when BTI is enabled. Migrate all logic to _libkvmplat_start() to facilitate BTI. Signed-off-by: Michalis Pappas <mpappas@fastmail.fm>
Update assembly implementation of SMCCC conduits with the necessary PAuth and BTI instructions. This fixes an issue where any code that invokes an SMCCC conduit will cause a Data Abort, due to the lack of branch protection instructions. That will bring the system into an infinite loop, as `system_off()` invokes a PSCI call, yet again via an SMCCC conduit. Signed-off-by: Michalis Pappas <mpappas@fastmail.fm>
1ddd550 to
3e5e3ee
Compare
|
Rebased to |
|
✅ Checkpatch passed Beep boop! I ran Unikraft's
|
rene
left a comment
There was a problem hiding this comment.
@michpappas , looks good to me.
Reviewed-by: Renê de Souza Pinto rene@renesp.com.br
vladandrew
left a comment
There was a problem hiding this comment.
Great addition to Unikraft!
Approved-by: Vlad Badoiu vlad_andrei.badoiu@upb.ro
Currently _libkvmplat_start() switches to the runtime stack via a trampoline before passing control to ukboot. This appears to be unnecessary and introduces complications when BTI is enabled. Migrate all logic to _libkvmplat_start() to facilitate BTI. Signed-off-by: Michalis Pappas <mpappas@fastmail.fm> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Renê de Souza Pinto <rene@renesp.com.br> Approved-by: Vlad Badoiu <vlad_andrei.badoiu@upb.ro> Tested-by: Unikraft CI <monkey@unikraft.io> GitHub-Closes: #421
Update assembly implementation of SMCCC conduits with the necessary PAuth and BTI instructions. This fixes an issue where any code that invokes an SMCCC conduit will cause a Data Abort, due to the lack of branch protection instructions. That will bring the system into an infinite loop, as `system_off()` invokes a PSCI call, yet again via an SMCCC conduit. Signed-off-by: Michalis Pappas <mpappas@fastmail.fm> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Renê de Souza Pinto <rene@renesp.com.br> Approved-by: Vlad Badoiu <vlad_andrei.badoiu@upb.ro> Tested-by: Unikraft CI <monkey@unikraft.io> GitHub-Closes: #421
Prerequisite checklist
checkpatch.plon your commit series before opening this PR;Base target
arm64]Additional configuration
This PR introduces a new Kconfig option, CONFIG_ARM64_FEAT_BTI. For details, see below.
Description of changes
FEAT_BTI is a hardware protection against JOP-like attacks.
To do that, it introduces:
BTI instructions, aka landing pads, are placed by the compiler at branch targets. On runtime, branches that do not land on a BTI instruction trigger an Branch Target Exception.
The GP field indicates whether a page is guarded with BTI. This is allows backwards compatibilty, by disabling BTI on pages that contain non-BTI guarded code. Notice that BTI instructions on unguarded pages execute as NOP.
PSTATE.BTYPE encodes the type of an indirect jump, ie the branch instruction, the registers used to carry parameters, and whether the target page is guarded or or not. When an indirect branch is taken, the processor checks whether PSATE.BTYPE matches the type of the branch target, and on negative match it generates an Branch Target Exception. The purpose of this is to further limit the scope of possible gadgets among BTI protected branches. Notice that there are exceptions to this. For details see D5.4.4 in [2].
Architecture Support
Armv8.5-a introduces FEAT_BTI as a mandatory feature. This feature is only available in AArch64.
GCC Support
GCC-9 introduces support for Armv8.5-A. BTI is supported through the
-mbranch-protectionparameter.The parameters passed to -mbranch-protection are interpreted as:
+leafmodifier enables protection for leaf functions.GCC-9 comes with an issue where under certain conditions incorrect BTI instructions are generated. Due of that issue, for BTI support in Unikraft we mandate GCC => 10.
Backwards Compatibility
BTI is implemented as hint instructions. Processors based on older architecture revisions will execute these as NOP.
Changes introduced in this PR
This PR adds BTI support on arm64-based platforms through a new Kconfig option CONFIG_ARM64_FEAT_BTI. Enabling this option instructs GCC to instrument branch targets with landing pads. The default PTE attributes of executable pages and blocks are updated to set the GP attribute when BTI is enabled.
Platform Requirements
As GCC only generates BTI instructions for C code, platforms need to make sure that assembly functions that are called through indirect branching are updated with landing pads before BTI support is enabled.
References