Indirect Branch Tracking (IBT) provides protection against CALL-/JMP-
oriented programming attacks. It is active when the kernel has this
feature enabled, and the processor and the application support it.
When this feature is enabled, legacy non-IBT applications continue to
work, but without IBT protection.
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
---
arch/x86/Kconfig | 19 +++++++++++++++++++
arch/x86/include/asm/disabled-features.h | 8 +++++++-
2 files changed, 26 insertions(+), 1 deletion(-)
IBT state machine tracks CALL/JMP instructions. When a such instruction is
executed and before arriving at an ENDBR, it is in WAIT_FOR_ENDBR state,
which can be read from CET_WAIT_ENDBR bit of MSR_IA32_U_CET.
Further details are described in Intel SDM Vol. 1, Sec. 18.3.
In handling signals, WAIT_FOR_ENDBR state is saved/restored with a new
UC_WAIT_ENDBR flag being introduced.
A legacy IA32 signal frame does not have ucontext, and cannot be supported
with a uc flag. Thus, IBT feature is not supported for ia32 app's, which
is handled in a separate patch.
Signed-off-by: Yu-cheng Yu <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <redacted>
Cc: Florian Weimer <redacted>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <redacted>
Link: https://lore.kernel.org/linux-api/f6e61dae-9805-c855-8873-7481ceb7ea79@intel.com/
---
arch/x86/ia32/ia32_signal.c | 15 ++++++++---
arch/x86/include/asm/cet.h | 4 +++
arch/x86/include/uapi/asm/ucontext.h | 5 ++++
arch/x86/kernel/ibt.c | 36 ++++++++++++++++++++++++++++
arch/x86/kernel/signal.c | 6 +++++
5 files changed, 64 insertions(+), 3 deletions(-)
In a signal, a task's IBT status needs to be saved to the signal frame, and
later restored in sigreturn. For the purpose, previous versions of the
series add a new struct to the signal frame. However, a new signal frame
format (or re-using a reserved space) introduces complex compatibility
issues.
In the discussion (see link below), Andy Lutomirski proposed using a
ucontext flag. The approach is clean and eliminates most compatibility
issues.
However, a legacy IA32 signal frame does not have ucontext and cannot
support a uc flag. Thus,
- Disable IBT for ia32.
- In ia32 sigreturn, verify ibt is disabled.
Signed-off-by: Yu-cheng Yu <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <redacted>
Cc: Florian Weimer <redacted>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <redacted>
Link: https://lore.kernel.org/linux-api/f6e61dae-9805-c855-8873-7481ceb7ea79@intel.com/
---
arch/x86/ia32/ia32_signal.c | 7 +++++++
arch/x86/include/asm/elf.h | 13 ++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
An ELF file's .note.gnu.property indicates features the file supports.
The property is parsed at loading time and passed to arch_setup_elf_
property(). Update it for Indirect Branch Tracking.
Signed-off-by: Yu-cheng Yu <redacted>
Cc: Kees Cook <redacted>
---
v27:
- Remove selecting of ARCH_USE_GNU_PROPERTY and ARCH_BINFMT_ELF_STATE,
since they are already selected by X86_64.
arch/x86/kernel/process_64.c | 8 ++++++++
1 file changed, 8 insertions(+)
Can you have IBT enabled but not shadow stack via kernel parameters?
Outside this diff it has:
if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
return -ENOTSUPP;
So if "no_user_shstk" is set, this can't be used for IBT. But the
kernel would attempt to enable IBT.
Also if so, the CR4 bit enabling logic needs adjusting in this IBT
series. If not, we should probably mention this in the docs and enforce
it. It would then follow the logic in Kconfig, so maybe the simplest.
Like maybe instead of no_user_shstk, just no_user_cet?
quoted hunk
return copy_to_user(ubuf, buf, sizeof(buf));
}
@@ -46,6 +49,8 @@ int prctl_cet(int option, u64 arg2)
return -EINVAL;
if (arg2 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
shstk_disable();
+ if (arg2 & GNU_PROPERTY_X86_FEATURE_1_IBT)
+ ibt_disable();
return 0;
case ARCH_X86_CET_LOCK:
Can you have IBT enabled but not shadow stack via kernel parameters?
Outside this diff it has:
if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
return -ENOTSUPP;
If shadow stack is disabled by the kernel parameter, IBT is also disabled.
So if "no_user_shstk" is set, this can't be used for IBT. But the
kernel would attempt to enable IBT.
It will not.
Also if so, the CR4 bit enabling logic needs adjusting in this IBT
series. If not, we should probably mention this in the docs and enforce
it. It would then follow the logic in Kconfig, so maybe the simplest.
Like maybe instead of no_user_shstk, just no_user_cet?
If shadow stack is disabled (from either Kconfig or kernel
command-line), then IBT is also disabled. However, we still need two
kernel parameters because no_user_ibt can be useful sometimes. I will
add a sentence in the document to indicate that IBT depends on shadow
stack.
Thanks,
Yu-cheng
Can you have IBT enabled but not shadow stack via kernel
parameters?
Outside this diff it has:
if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
return -ENOTSUPP;
If shadow stack is disabled by the kernel parameter, IBT is also
disabled.
Thanks for the clarification.
quoted
So if "no_user_shstk" is set, this can't be used for IBT. But the
kernel would attempt to enable IBT.
It will not.
Oh yea, I see the cpuid_deps part now. Sorry.
quoted
Also if so, the CR4 bit enabling logic needs adjusting in this IBT
series. If not, we should probably mention this in the docs and
enforce
it. It would then follow the logic in Kconfig, so maybe the
simplest.
Like maybe instead of no_user_shstk, just no_user_cet?
If shadow stack is disabled (from either Kconfig or kernel
command-line), then IBT is also disabled. However, we still need two
kernel parameters because no_user_ibt can be useful sometimes. I
will
add a sentence in the document to indicate that IBT depends on shadow
stack.
Yea, no_user_ibt seems useful. I meant that renaming no_user_shstk to
no_user_cet (or similar) would be more clear and self documenting,
since it intends to disable all user cet features and not just
shadowstack. And leaving no_user_ibt as is. Documentation works as well
though. Not major in any case.
ENDBR is a special new instruction for the Indirect Branch Tracking (IBT)
component of CET. IBT prevents attacks by ensuring that (most) indirect
branches and function calls may only land at ENDBR instructions. Branches
that don't follow the rules will result in control flow (#CF) exceptions.
ENDBR is a noop when IBT is unsupported or disabled. Most ENDBR
instructions are inserted automatically by the compiler, but branch
targets written in assembly must have ENDBR added manually.
Introduce ENDBR64/ENDBR32 macros.
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/include/asm/vdso.h | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
From: "H.J. Lu" <redacted>
ENDBR is a special new instruction for the Indirect Branch Tracking (IBT)
component of CET. IBT prevents attacks by ensuring that (most) indirect
branches and function calls may only land at ENDBR instructions. Branches
that don't follow the rules will result in control flow (#CF) exceptions.
ENDBR is a noop when IBT is unsupported or disabled. Most ENDBR
instructions are inserted automatically by the compiler, but branch
targets written in assembly must have ENDBR added manually.
Add that to __kernel_vsyscall entry point.
Signed-off-by: H.J. Lu <redacted>
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
---
arch/x86/entry/vdso/vdso32/system_call.S | 2 ++
1 file changed, 2 insertions(+)
ENDBR is a special new instruction for the Indirect Branch Tracking (IBT)
component of CET. IBT prevents attacks by ensuring that (most) indirect
branches and function calls may only land at ENDBR instructions. Branches
that don't follow the rules will result in control flow (#CF) exceptions.
ENDBR is a noop when IBT is unsupported or disabled. Most ENDBR
instructions are inserted automatically by the compiler, but branch
targets written in assembly must have ENDBR added manually.
Add ENDBR to __vdso_sgx_enter_enclave() branch targets.
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/entry/vdso/vsgx.S | 4 ++++
1 file changed, 4 insertions(+)
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-05-22 22:47:12
On Fri, May 21, 2021 at 03:15:31PM -0700, Yu-cheng Yu wrote:
ENDBR is a special new instruction for the Indirect Branch Tracking (IBT)
component of CET. IBT prevents attacks by ensuring that (most) indirect
branches and function calls may only land at ENDBR instructions. Branches
that don't follow the rules will result in control flow (#CF) exceptions.
ENDBR is a noop when IBT is unsupported or disabled. Most ENDBR
instructions are inserted automatically by the compiler, but branch
targets written in assembly must have ENDBR added manually.
Add ENDBR to __vdso_sgx_enter_enclave() branch targets.
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
On Fri, May 21, 2021 at 03:15:31PM -0700, Yu-cheng Yu wrote:
quoted
ENDBR is a special new instruction for the Indirect Branch Tracking (IBT)
component of CET. IBT prevents attacks by ensuring that (most) indirect
branches and function calls may only land at ENDBR instructions. Branches
that don't follow the rules will result in control flow (#CF) exceptions.
ENDBR is a noop when IBT is unsupported or disabled. Most ENDBR
instructions are inserted automatically by the compiler, but branch
targets written in assembly must have ENDBR added manually.
Add ENDBR to __vdso_sgx_enter_enclave() branch targets.
Signed-off-by: Yu-cheng Yu <redacted>
Reviewed-by: Kees Cook <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>