[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 06/10] x86: Temporary disable SMAP to legally access user pages in kernel mode
>>> On 06.05.14 at 12:08, <feng.wu@xxxxxxxxx> wrote: > Use STAC/CLAC to temporarily disable SMAP to allow legal accesses to > user pages in kernel mode > > STAC/CLAC is not needed for compat_create_bounce_frame, since in this > chunk of code, it only accesses the pv guest's kernel stack, which is > in ring 1 for 32-bit pv guests. > > Signed-off-by: Feng Wu <feng.wu@xxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > xen/arch/x86/traps.c | 12 ++++++++++++ > xen/arch/x86/usercopy.c | 6 ++++++ > xen/arch/x86/x86_64/entry.S | 2 ++ > xen/include/asm-x86/uaccess.h | 8 ++++++-- > xen/include/asm-x86/x86_64/system.h | 4 +++- > 5 files changed, 29 insertions(+), 3 deletions(-) > > diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c > index 45070bb..19c96d5 100644 > --- a/xen/arch/x86/traps.c > +++ b/xen/arch/x86/traps.c > @@ -3811,6 +3811,18 @@ unsigned long do_get_debugreg(int reg) > > void asm_domain_crash_synchronous(unsigned long addr) > { > + /* > + * We need clear AC bit here because in entry.S AC is set > + * by ASM_STAC to temporarily allow accesses to user pages > + * which is prevented by SMAP by default. > + * > + * For some code paths, where this function is called, clac() > + * is not needed, but adding clac() here instead of each place > + * asm_domain_crash_synchronous() is called can reduce the code > + * redundancy, and it is harmless as well. > + */ > + clac(); > + > if ( addr == 0 ) > addr = this_cpu(last_extable_addr); > > diff --git a/xen/arch/x86/usercopy.c b/xen/arch/x86/usercopy.c > index b79202b..4cc78f5 100644 > --- a/xen/arch/x86/usercopy.c > +++ b/xen/arch/x86/usercopy.c > @@ -14,6 +14,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void > *from, unsigned n) > { > unsigned long __d0, __d1, __d2, __n = n; > > + stac(); > asm volatile ( > " cmp $"STR(2*BYTES_PER_LONG-1)",%0\n" > " jbe 1f\n" > @@ -42,6 +43,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void > *from, unsigned n) > : "=&c" (__n), "=&D" (__d0), "=&S" (__d1), "=&r" (__d2) > : "0" (__n), "1" (to), "2" (from), "3" (__n) > : "memory" ); > + clac(); > > return __n; > } > @@ -51,6 +53,7 @@ __copy_from_user_ll(void *to, const void __user *from, > unsigned n) > { > unsigned long __d0, __d1, __d2, __n = n; > > + stac(); > asm volatile ( > " cmp $"STR(2*BYTES_PER_LONG-1)",%0\n" > " jbe 1f\n" > @@ -85,6 +88,7 @@ __copy_from_user_ll(void *to, const void __user *from, > unsigned n) > : "=&c" (__n), "=&D" (__d0), "=&S" (__d1), "=&r" (__d2) > : "0" (__n), "1" (to), "2" (from), "3" (__n) > : "memory" ); > + clac(); > > return __n; > } > @@ -113,6 +117,7 @@ copy_to_user(void __user *to, const void *from, unsigned > n) > #define __do_clear_user(addr,size) \ > do { \ > long __d0; \ > + stac(); \ > __asm__ __volatile__( \ > "0: rep; stosl\n" \ > " movl %2,%0\n" \ > @@ -126,6 +131,7 @@ do { > \ > _ASM_EXTABLE(1b,2b) \ > : "=&c"(size), "=&D" (__d0) \ > : "r"(size & 3), "0"(size / 4), "1"((long)addr), "a"(0)); > \ > + clac(); \ > } while (0) > > /** > diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S > index 205251d..dce6eb5 100644 > --- a/xen/arch/x86/x86_64/entry.S > +++ b/xen/arch/x86/x86_64/entry.S > @@ -379,6 +379,7 @@ __UNLIKELY_END(create_bounce_frame_bad_sp) > movb TRAPBOUNCE_flags(%rdx),%cl > subq $40,%rsi > movq UREGS_ss+8(%rsp),%rax > + ASM_STAC > .Lft2: movq %rax,32(%rsi) # SS > movq UREGS_rsp+8(%rsp),%rax > .Lft3: movq %rax,24(%rsi) # RSP > @@ -423,6 +424,7 @@ UNLIKELY_END(bounce_failsafe) > .Lft12: movq %rax,8(%rsi) # R11 > movq UREGS_rcx+8(%rsp),%rax > .Lft13: movq %rax,(%rsi) # RCX > + ASM_CLAC > /* Rewrite our stack frame and return to guest-OS mode. */ > /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. > */ > /* Also clear AC: alignment checks shouldn't trigger in kernel > mode. */ > diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h > index 88b4ba2..92bc322 100644 > --- a/xen/include/asm-x86/uaccess.h > +++ b/xen/include/asm-x86/uaccess.h > @@ -146,6 +146,7 @@ struct __large_struct { unsigned long buf[100]; }; > * aliasing issues. > */ > #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ > + stac(); \ > __asm__ __volatile__( \ > "1: mov"itype" %"rtype"1,%2\n" \ > "2:\n" \ > @@ -155,9 +156,11 @@ struct __large_struct { unsigned long buf[100]; }; > ".previous\n" \ > _ASM_EXTABLE(1b, 3b) \ > : "=r"(err) \ > - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err)) > + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err)); \ > + clac(); > > #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ > + stac(); \ > __asm__ __volatile__( \ > "1: mov"itype" %2,%"rtype"1\n" \ > "2:\n" \ > @@ -168,7 +171,8 @@ struct __large_struct { unsigned long buf[100]; }; > ".previous\n" \ > _ASM_EXTABLE(1b, 3b) \ > : "=r"(err), ltype (x) \ > - : "m"(__m(addr)), "i"(errret), "0"(err)) > + : "m"(__m(addr)), "i"(errret), "0"(err)); \ > + clac(); > > /** > * __copy_to_user: - Copy a block of data into user space, with less > checking > diff --git a/xen/include/asm-x86/x86_64/system.h > b/xen/include/asm-x86/x86_64/system.h > index 20f038b..b6341ad1 100644 > --- a/xen/include/asm-x86/x86_64/system.h > +++ b/xen/include/asm-x86/x86_64/system.h > @@ -12,6 +12,7 @@ > * is the same as the initial value of _o then _n is written to location > _p. > */ > #define __cmpxchg_user(_p,_o,_n,_isuff,_oppre,_regtype) \ > + stac(); \ > asm volatile ( \ > "1: lock; cmpxchg"_isuff" %"_oppre"2,%3\n" \ > "2:\n" \ > @@ -22,7 +23,8 @@ > _ASM_EXTABLE(1b, 3b) \ > : "=a" (_o), "=r" (_rc) \ > : _regtype (_n), "m" (*__xg((volatile void *)_p)), "0" (_o), "1" > (0) \ > - : "memory"); > + : "memory"); \ > + clac(); > > #define cmpxchg_user(_p,_o,_n) \ > ({ \ > -- > 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |