[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 3/7] x86/altcall: Optimise away endbr64 instruction where possible
On 14.02.2022 14:31, Andrew Cooper wrote: > On 14/02/2022 13:06, Jan Beulich wrote: >> On 14.02.2022 13:56, Andrew Cooper wrote: >>> @@ -330,6 +333,41 @@ static void init_or_livepatch >>> _apply_alternatives(struct alt_instr *start, >>> add_nops(buf + a->repl_len, total_len - a->repl_len); >>> text_poke(orig, buf, total_len); >>> } >>> + >>> + /* >>> + * Clobber endbr64 instructions now that altcall has finished >>> optimising >>> + * all indirect branches to direct ones. >>> + */ >>> + if ( force && cpu_has_xen_ibt ) >>> + { >>> + void *const *val; >>> + unsigned int clobbered = 0; >>> + >>> + /* >>> + * This is some minor structure (ab)use. We walk the entire >>> contents >>> + * of .init.{ro,}data.cf_clobber as if it were an array of >>> pointers. >>> + * >>> + * If the pointer points into .text, and at an endbr64 instruction, >>> + * nop out the endbr64. This causes the pointer to no longer be a >>> + * legal indirect branch target under CET-IBT. This is a >>> + * defence-in-depth measure, to reduce the options available to an >>> + * adversary who has managed to hijack a function pointer. >>> + */ >>> + for ( val = __initdata_cf_clobber_start; >>> + val < __initdata_cf_clobber_end; >>> + val++ ) >>> + { >>> + void *ptr = *val; >>> + >>> + if ( !is_kernel_text(ptr) || !is_endbr64(ptr) ) >>> + continue; >>> + >>> + add_nops(ptr, 4); >> This literal 4 would be nice to have a #define next to where the ENDBR64 >> encoding has its central place. > > We don't have an encoding of ENDBR64 in a central place. > > The best you can probably have is > > #define ENDBR64_LEN 4 > > in endbr.h ? Perhaps. That's not in this series nor in staging already, so it's a little hard to check. By "central place" I really meant is_enbr64() if that's the only place where the encoding actually appears. >>> --- a/xen/arch/x86/xen.lds.S >>> +++ b/xen/arch/x86/xen.lds.S >>> @@ -221,6 +221,12 @@ SECTIONS >>> *(.initcall1.init) >>> __initcall_end = .; >>> >>> + . = ALIGN(POINTER_ALIGN); >>> + __initdata_cf_clobber_start = .; >>> + *(.init.data.cf_clobber) >>> + *(.init.rodata.cf_clobber) >>> + __initdata_cf_clobber_end = .; >>> + >>> *(.init.data) >>> *(.init.data.rel) >>> *(.init.data.rel.*) >> With r/o data ahead and r/w data following, may I suggest to flip the >> order of the two section specifiers you add? > > I don't follow. This is all initdata which is merged together into a > single section. > > The only reason const data is split out in the first place is to appease > the toolchains, not because it makes a difference. It's marginal, I agree, but it would still seem more clean to me if all (pseudo) r/o init data lived side by side. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |