From: Chao Gao The #CP exceptions include an error code that provides additional information about how the exception occurred. Previously, CET tests simply printed these error codes without validation. Enhance the CET tests to validate the #CP error code. This requires the run_in_user() infrastructure to catch the exception vector, error code, and rflags, similar to what check_exception_table() does. Signed-off-by: Chao Gao Signed-off-by: Mathias Krause Signed-off-by: Sean Christopherson --- lib/x86/usermode.c | 4 ++++ x86/cet.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c index c3ec0ad7..f896e3bd 100644 --- a/lib/x86/usermode.c +++ b/lib/x86/usermode.c @@ -23,6 +23,10 @@ static void restore_exec_to_jmpbuf(void) static void restore_exec_to_jmpbuf_exception_handler(struct ex_regs *regs) { + this_cpu_write_exception_vector(regs->vector); + this_cpu_write_exception_rflags_rf((regs->rflags >> 16) & 1); + this_cpu_write_exception_error_code(regs->error_code); + /* longjmp must happen after iret, so do not do it now. */ regs->rip = (unsigned long)&restore_exec_to_jmpbuf; regs->cs = KERNEL_CS; diff --git a/x86/cet.c b/x86/cet.c index 7635fe34..0452851d 100644 --- a/x86/cet.c +++ b/x86/cet.c @@ -94,13 +94,13 @@ int main(int ac, char **av) printf("Unit test for CET user mode...\n"); run_in_user((usermode_func)cet_shstk_func, CP_VECTOR, 0, 0, 0, 0, &rvc); - report(rvc, "Shadow-stack protection test."); + report(rvc && exception_error_code() == 1, "Shadow-stack protection test."); /* Enable indirect-branch tracking */ wrmsr(MSR_IA32_U_CET, ENABLE_IBT_BIT); run_in_user((usermode_func)cet_ibt_func, CP_VECTOR, 0, 0, 0, 0, &rvc); - report(rvc, "Indirect-branch tracking test."); + report(rvc && exception_error_code() == 3, "Indirect-branch tracking test."); write_cr4(read_cr4() & ~X86_CR4_CET); wrmsr(MSR_IA32_U_CET, 0); -- 2.52.0.rc1.455.g30608eb744-goog