[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 13:56, Andrew Cooper wrote: > With altcall, we convert indirect branches into direct ones. With that > complete, none of the potential targets need an endbr64 instruction. > > Furthermore, removing the endbr64 instructions is a security defence-in-depth > improvement, because it limits the options available to an attacker who has > managed to hijack a function pointer. > > Introduce new .init.{ro,}data.cf_clobber sections. Have _apply_alternatives() > walk over this, looking for any pointers into .text, and clobber an endbr64 > instruction if found. This is some minor structure (ab)use but it works > alarmingly well. > > Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> with two remarks, which ideally would be addressed by respective small adjustments: > @@ -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. > --- 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? Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |