[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 10/14] x86/extable: Adjust extable handling to be shadow stack compatible
On 27.05.2020 21:18, Andrew Cooper wrote: > @@ -400,6 +400,18 @@ unsigned long get_stack_trace_bottom(unsigned long sp) > } > } > > +static unsigned long get_shstk_bottom(unsigned long sp) > +{ > + switch ( get_stack_page(sp) ) > + { > +#ifdef CONFIG_XEN_SHSTK > + case 0: return ROUNDUP(sp, IST_SHSTK_SIZE) - sizeof(unsigned long); > + case 5: return ROUNDUP(sp, PAGE_SIZE) - sizeof(unsigned long); PRIMARY_SHSTK_SLOT please and, if introduced as suggested for the earlier patch, IST_SHSTK_SLOT in the earlier line. > @@ -763,6 +775,56 @@ 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) > +{ > + unsigned long ssp, *ptr, *base; > + > + asm ( "rdsspq %0" : "=r" (ssp) : "0" (1) ); > + if ( ssp == 1 ) > + return; > + > + ptr = _p(ssp); > + base = _p(get_shstk_bottom(ssp)); > + > + for ( ; ptr < base; ++ptr ) > + { > + /* > + * Search for %rip. The shstk currently looks like this: > + * > + * ... [Likely pointed to by SSP] > + * %cs [== regs->cs] > + * %rip [== regs->rip] > + * SSP [Likely points to 3 slots higher, above %cs] > + * ... [call tree to this function, likely 2/3 slots] > + * > + * and we want to overwrite %rip with fixup. There are two > + * complications: > + * 1) We cant depend on SSP values, because they won't differ by 3 > + * slots if the exception is taken on an IST stack. > + * 2) There are synthetic (unrealistic but not impossible) > scenarios > + * where %rip can end up in the call tree to this function, so > we > + * can't check against regs->rip alone. > + * > + * Check for both reg->rip and regs->cs matching. Nit: regs->rip > + */ > + > + if ( ptr[0] == regs->rip && ptr[1] == regs->cs ) > + { > + asm ( "wrssq %[fix], %[stk]" > + : [stk] "=m" (*ptr) Could this be ptr[0], to match the if()? Considering how important it is that we don't fix up the wrong stack location here, I continue to wonder if we wouldn't better also include the SSP value on the stack in the checking, at the very least by way of an ASSERT() or BUG_ON(). Since, with how the code is currently written, this would require a somewhat odd looking ptr[-1] I also wonder whether "while ( ++ptr < base )" as the loop header wouldn't be better. The first entry on the stack can't be the RIP we look for anyway, can it? > --- a/xen/arch/x86/x86_64/entry.S > +++ b/xen/arch/x86/x86_64/entry.S > @@ -708,7 +708,16 @@ exception_with_ints_disabled: > call search_pre_exception_table > testq %rax,%rax # no fixup code for faulting EIP? > jz 1b > - movq %rax,UREGS_rip(%rsp) > + movq %rax,UREGS_rip(%rsp) # fixup regular stack > + > +#ifdef CONFIG_XEN_SHSTK > + mov $1, %edi > + rdsspq %rdi > + cmp $1, %edi > + je .L_exn_shstk_done > + wrssq %rax, (%rdi) # fixup shadow stack According to the comment in extable_shstk_fixup(), isn't the value to be replaced at 8(%rdi)? Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |