[PATCH V3 0/9] objtool changes to check retpoline code

From: Alexandre Chartre
Date: Tue Apr 14 2020 - 06:56:13 EST


Hi,

This is version 3 of the patchset previously named "objtool changes to
remove all ANNOTATE_NOSPEC_ALTERNATIVE". This patchset proposes two
main changes:

1. Add intra-function call support to objtool. This allows objtool
to check code like retpoline and RSB stuffing. Such code is present
in alternative and it is not currently checked because of
ANNOTATE_NOSPEC_ALTERNATIVE directives.

2. Add alternative code validation in objtool. For stack unwinding to
work, Peter and Josh have clearly explained that alternative code
should have the same stack change sequence as the original code.
This patchset adds this capability to objtool.

After changes 1, we could remove the ANNOTATE_SPEC_ALTERNATIVE directives
from retpoline/RSB alternatives, and alternatives would be correclty checked
by objtool. But, because of changes 2, objtool would now report inconsistency
in alternatives, like this:

AS arch/x86/lib/retpoline.o
arch/x86/lib/retpoline.o: warning: objtool: __x86_indirect_thunk_rax()+0x0: error in alternative
arch/x86/lib/retpoline.o: warning: objtool: .altinstr_replacement+0x0: in alternative 1
arch/x86/lib/retpoline.o: warning: objtool: .altinstr_replacement+0x5: misaligned alternative state change
arch/x86/lib/retpoline.o: warning: objtool: .altinstr_replacement+0x11: in alternative 2
arch/x86/lib/retpoline.o: warning: objtool: .altinstr_replacement+0x14: misaligned alternative state change

So this pachset doesn't remove ANNOTATE_NOSPEC_ALTERNATIVE directives
(unlike v1 and v2). But it makes objtool able to detect inconsistent
alternatives. Then such alternative will need to be refactored to
have stack unwinding information compatible with the original code.
For example, here is Peter suggestion for retpoline code:
https://lkml.org/lkml/2020/4/8/905


Changes:

v2->v3:
- rebase on v5.7-rc1
- add alternative code validation in objtool
- add return address unwind hints
- track return address to correctly handle ret with intra-function call
- remove inclusion of PeterZ UNWIND_HINT_RET_OFFSET patch
- move alt_group changes to appropriate patch
- move stack changes for calls to INSN_CALL decode

v1->v2:
- replace RETPOLINE_RET with PeterZ UNWIND_HINT_RET_OFFSET
- make objtool intra-function call action architecture dependent
- objtool now automatically detects and validates all intra-function
calls but it issues a warning if the call was not explicitly tagged
- change __FILL_RETURN_BUFFER to work with objtool
- add generic ANNOTATE_INTRA_FUNCTION_CALL macro
- remove all ANNOTATE_SPEC_ALTERNATIVE (even for __FILL_RETURN_BUFFER)

Thanks,

alex.

-----

Alexandre Chartre (9):
objtool: is_fentry_call() crashes if call has no destination
objtool: Allow branches within the same alternative.
objtool: Add support for intra-function calls
objtool: Handle return instruction with intra-function call
objtool: Add return address unwind hints
objtool: Report inconsistent stack changes in alternative
x86/speculation: Change __FILL_RETURN_BUFFER to work with objtool
x86/speculation: Add return address unwind hints to retpoline and RSB
stuffing
x86/speculation: Annotate intra-function calls

arch/x86/include/asm/nospec-branch.h | 42 +-
arch/x86/include/asm/orc_types.h | 2 +
arch/x86/include/asm/unwind_hints.h | 23 +
include/linux/frame.h | 11 +
tools/arch/x86/include/asm/orc_types.h | 2 +
.../Documentation/stack-validation.txt | 8 +
tools/objtool/arch/x86/decode.c | 13 +
tools/objtool/check.c | 480 ++++++++++++++++--
tools/objtool/check.h | 8 +-
9 files changed, 545 insertions(+), 44 deletions(-)

--
2.18.2