Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: arm32: sm: invalidate branch predictor #2047

Merged
merged 1 commit into from
Jan 8, 2018

Conversation

jenswi-linaro
Copy link
Contributor

  • If built with internal secure monitor, invalidates branch predictor
    on non-secure entry.
  • If built for usage with ARM-TF, invalidates branch predictor on
    entry.

Fixes CVE-2017-5715

Signed-off-by: Jens Wiklander [email protected]

@jenswi-linaro jenswi-linaro mentioned this pull request Jan 4, 2018
@@ -166,6 +166,10 @@ UNWIND( .cantunwind)
b .sm_exit

.smc_from_nsec:
/* Invalidate the branch predictor. */
write_bpiallis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Inner Shareable? Wouldn't write_bpiall be enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I'll fix.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is late to apply the fix as the BTB speculation can occur on the unconditional branch at Line 258. BPIALL needs to be done prior to any branch instruction in Secure world. Its not easy to do this but we have an upcoming patch in ARM TF which will demonstrate this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@soby-mathew , so you are saying this should be done before actually doing any jump from the vector table. Will this also affect the thread vector table? I'd guess that it doesn't affect that, agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, does it involve multiple vectors?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jenswi-linaro, the way we do it is to have ORR (Or ADD) instruction at each vector entry to encode a bit pattern into an available General Purpose register. We use the sp for this and ensure the stack/whatever sp is pointing to is aligned so that the LSB can be used for the bit pattern encoding. Then the BPIALL is done and the bit pattern is extracted to get the vector entry. Finally we jump to the correct handler corresponding to the vector entry.

If the sp is pointing to address that is naturally aligned to 256 bytes then ORR can be used to encode the bit pattern (one bit per vector entry). Else ADD can be used to encode values from 0 to 7 for each vector entry and the sp needs to point to an address that is 8 byte aligned.

That's the general idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, clever. Thanks, I'll do that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All branches are subject to prediction on some Arm CPUs.

ARM Technical Reference Manual for A57 on predicted instructions:

6.5.1 Predicted and non-predicted instructions
This section describes the instructions that the processor predicts.

Unless otherwise specified, the list applies to A32, T32, and A64 instructions. As a general rule, the branch prediction hardware predicts all branch instructions regardless of the addressing mode, including:

  • Conditional branches.
  • Unconditional branches.
  • Indirect branches.
  • Branches that switch between ARM and Thumb states.
  • PC destination data processing operations.
  • BXJ, because of the inclusion of the trivial Jazelle implementation, this degenerates to a BX instruction. There is no BXJ instruction in A64.

However, the following branch instructions are not predicted:

  • AArch32 instructions with the S suffix are not predicted because they are typically used when returning from exceptions and have side effects that can change privilege mode and Security state.
  • All mode or Exception level changing instructions.

In Thumb state, you can make a branch that is normally encoded as unconditional conditional by including an If-Then (IT) block. It is then treated as a normal conditional branch.

see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382448710808.html

Copy link

@athoelke athoelke Jan 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[oops - missed that Soby had already mentioned this in his comment]

Jens - we're also testing a _version that has less constraint on the SP alignment and only needs 3 bits of SP to encode the vector before invalidating the branch predictor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@athoelke thanks for the reference, quite helpful.

I suppose this section will need some rework however:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382448710808.html
;-)

.macro maybe_invalidate_bp
#ifdef CFG_WITH_ARM_TRUSTED_FW
/* Invalidate the branch predictor. */
write_bpiallis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is BP invalidate needed at all in this file when CFG_WITH_ARM_TRUSTED_FW=y? Isn't EL3 supposed to take care of it if needed? (I'm referring to ARM-TF pull request 1214).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was asked to do it like this, I guess this was before ARM-software/arm-trusted-firmware#1214 existed.
@jbech-linaro, do you know if this is still needed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @jforissier is right here, we don't need to do it if it is done by Arm-TF. We need to make the branch invalidate when we are running our own monitor (and therefore responsible for the switch).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's drop this.

@jenswi-linaro
Copy link
Contributor Author

Update
I'll update the commit message when squashing.

@jbech-linaro
Copy link
Contributor

Reviewed-by: Joakim Bech <[email protected]>

@jforissier
Copy link
Contributor

What about sm_fiq_entry?

@jenswi-linaro
Copy link
Contributor Author

@jforissier, I'll fix sm_fiq_entry() too.

@jenswi-linaro
Copy link
Contributor Author

Update

Copy link

@soby-mathew soby-mathew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. The only comment being introducing a build flag so to apply this only for affected platforms ?

@jenswi-linaro
Copy link
Contributor Author

Update, add config flag default enabled for this workaround.

@@ -31,6 +31,12 @@ platform-hard-float-enabled := y
endif
endif

# Adds protection against CVE-2017-5715 also know as Spectre
# (https://spectreattack.com)
# See also https://developer.arm.com/-/media/Files/pdf/Cache_Speculation_Side-channels.pdf?revision=966364ce-10aa-4580-8431-7e4ed42fb90b&la=en
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may shorten the URL, the parameters are useless

@jenswi-linaro
Copy link
Contributor Author

Update

@jforissier
Copy link
Contributor

Reviewed-by: Jerome Forissier <[email protected]>

@jbech-linaro
Copy link
Contributor

Reviewed-by: Joakim Bech <[email protected]>

@jforissier
Copy link
Contributor

What about entry via svc? I would think that path should be protected, too.

If build with secure monitor and CFG_CORE_WORKAROUND_SPECTRE_BP=y
invalidate branch predictor on non-secure entry.

Fixes CVE-2017-5715

Reviewed-by: Jerome Forissier <[email protected]>
Reviewed-by: Joakim Bech <[email protected]>
Signed-off-by: Jens Wiklander <[email protected]>
@jenswi-linaro
Copy link
Contributor Author

I'll create another PR for svc

@jforissier
Copy link
Contributor

OK, sounds good.

@jenswi-linaro
Copy link
Contributor Author

Rebased, squashed and tags applied.

@jforissier jforissier merged commit 3bc90f3 into OP-TEE:master Jan 8, 2018
@jenswi-linaro jenswi-linaro deleted the cve-2017-5715 branch January 8, 2018 12:43
@jforissier jforissier changed the title core: arm32: invalidate branch predictor core: arm32: sm: invalidate branch predictor Jan 12, 2018
nop /* 0:000 FIQ */

/* Invalidate the branch predictor for the current processor. */
write_bpiall
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work on Cortex-A15?
#2055 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, not as intended at least.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BPIALL is not effective in invalidating the branch predictor on A15. An ICALLU with the ACTLR[0] set to 1 need to be done on Cortex-A15. The ARM TF advisory has been updated with this info. This would also mean the fix needs to detect the CPU type at runtime and apply the appropriate workaround.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #2065

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants