[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/cet: Fix shskt manipulation error with BUGFRAME_{warn,run_fn}
commit 35727551c0703493a2240e967cffc3063b13d49c Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Thu Aug 12 17:39:16 2021 +0100 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Mon Aug 16 16:03:20 2021 +0100 x86/cet: Fix shskt manipulation error with BUGFRAME_{warn,run_fn} This was a clear oversight in the original CET work. The BUGFRAME_run_fn and BUGFRAME_warn paths update regs->rip without an equivalent adjustment to the shadow stack, causing IRET to suffer #CP because of the mismatch. One subtle, and therefore fragile, aspect of extable_shstk_fixup() was that it required regs->rip to have its old value as a cross-check that the right word in the shadow stack was being edited. Rework extable_shstk_fixup() into fixup_exception_return() which takes ownership of the update to both the regular and shadow stacks, ensuring that the regs->rip update is ordered correctly. Use the new fixup_exception_return() for BUGFRAME_run_fn and BUGFRAME_warn to ensure that the shadow stack is updated too. Fixes: 209fb9919b50 ("x86/extable: Adjust extable handling to be shadow stack compatible") Reported-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Tested-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/traps.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index e60af16ddd..30eefbad48 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -777,13 +777,15 @@ static void do_reserved_trap(struct cpu_user_regs *regs) trapnr, vec_name(trapnr), regs->error_code); } -static void extable_shstk_fixup(struct cpu_user_regs *regs, unsigned long fixup) +static void fixup_exception_return(struct cpu_user_regs *regs, + unsigned long fixup) { +#ifdef CONFIG_XEN_SHSTK unsigned long ssp, *ptr, *base; asm ( "rdsspq %0" : "=r" (ssp) : "0" (1) ); if ( ssp == 1 ) - return; + goto shstk_done; ptr = _p(ssp); base = _p(get_shstk_bottom(ssp)); @@ -814,7 +816,7 @@ static void extable_shstk_fixup(struct cpu_user_regs *regs, unsigned long fixup) asm ( "wrssq %[fix], %[stk]" : [stk] "=m" (ptr[0]) : [fix] "r" (fixup) ); - return; + goto shstk_done; } } @@ -824,6 +826,12 @@ static void extable_shstk_fixup(struct cpu_user_regs *regs, unsigned long fixup) * executing the interrupted context. */ BUG(); + + shstk_done: +#endif /* CONFIG_XEN_SHSTK */ + + /* Fixup the regular stack. */ + regs->rip = fixup; } static bool extable_fixup(struct cpu_user_regs *regs, bool print) @@ -842,10 +850,7 @@ static bool extable_fixup(struct cpu_user_regs *regs, bool print) vec_name(regs->entry_vector), regs->error_code, _p(regs->rip), _p(regs->rip), _p(fixup)); - if ( IS_ENABLED(CONFIG_XEN_SHSTK) ) - extable_shstk_fixup(regs, fixup); - - regs->rip = fixup; + fixup_exception_return(regs, fixup); this_cpu(last_extable_addr) = regs->rip; return true; @@ -1138,7 +1143,7 @@ void do_invalid_op(struct cpu_user_regs *regs) void (*fn)(struct cpu_user_regs *) = bug_ptr(bug); fn(regs); - regs->rip = (unsigned long)eip; + fixup_exception_return(regs, (unsigned long)eip); return; } @@ -1159,7 +1164,7 @@ void do_invalid_op(struct cpu_user_regs *regs) case BUGFRAME_warn: printk("Xen WARN at %s%s:%d\n", prefix, filename, lineno); show_execution_state(regs); - regs->rip = (unsigned long)eip; + fixup_exception_return(regs, (unsigned long)eip); return; case BUGFRAME_bug: -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |