[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 06/10] x86: Temporary disable SMAP to legally access user pages in kernel mode



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>
---
 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       |  4 ++++
 xen/include/asm-x86/x86_64/system.h |  2 ++
 5 files changed, 26 insertions(+)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index ed4ae2d..98044a3 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -3754,6 +3754,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..af96bf4 100644
--- a/xen/arch/x86/usercopy.c
+++ b/xen/arch/x86/usercopy.c
@@ -15,6 +15,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void 
*from, unsigned n)
     unsigned long __d0, __d1, __d2, __n = n;
 
     asm volatile (
+        ASM_STAC"\n"
         "    cmp  $"STR(2*BYTES_PER_LONG-1)",%0\n"
         "    jbe  1f\n"
         "    mov  %1,%0\n"
@@ -30,6 +31,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void 
*from, unsigned n)
         "    mov  %3,%0\n"
         "1:  rep movsb\n" /* ...remainder copied as bytes */
         "2:\n"
+        ASM_CLAC"\n"
         ".section .fixup,\"ax\"\n"
         "5:  add %3,%0\n"
         "    jmp 2b\n"
@@ -52,6 +54,7 @@ __copy_from_user_ll(void *to, const void __user *from, 
unsigned n)
     unsigned long __d0, __d1, __d2, __n = n;
 
     asm volatile (
+        ASM_STAC"\n"
         "    cmp  $"STR(2*BYTES_PER_LONG-1)",%0\n"
         "    jbe  1f\n"
         "    mov  %1,%0\n"
@@ -67,6 +70,7 @@ __copy_from_user_ll(void *to, const void __user *from, 
unsigned n)
         "    mov  %3,%0\n"
         "1:  rep; movsb\n" /* ...remainder copied as bytes */
         "2:\n"
+        ASM_CLAC"\n"
         ".section .fixup,\"ax\"\n"
         "5:  add %3,%0\n"
         "    jmp 6f\n"
@@ -114,10 +118,12 @@ copy_to_user(void __user *to, const void *from, unsigned 
n)
 do {                                                                   \
        long __d0;                                                      \
        __asm__ __volatile__(                                           \
+               ASM_STAC"\n"                                            \
                "0:     rep; stosl\n"                                   \
                "       movl %2,%0\n"                                   \
                "1:     rep; stosb\n"                                   \
                "2:\n"                                                  \
+               ASM_CLAC"\n"                                            \
                ".section .fixup,\"ax\"\n"                              \
                "3:     lea 0(%2,%0,4),%0\n"                            \
                "       jmp 2b\n"                                       \
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 2b7072d..4e17b90 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..ce1af4a 100644
--- a/xen/include/asm-x86/uaccess.h
+++ b/xen/include/asm-x86/uaccess.h
@@ -147,8 +147,10 @@ struct __large_struct { unsigned long buf[100]; };
  */
 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
        __asm__ __volatile__(                                           \
+               ASM_STAC"\n"                                            \
                "1:     mov"itype" %"rtype"1,%2\n"                      \
                "2:\n"                                                  \
+               ASM_CLAC"\n"                                            \
                ".section .fixup,\"ax\"\n"                              \
                "3:     mov %3,%0\n"                                    \
                "       jmp 2b\n"                                       \
@@ -159,8 +161,10 @@ struct __large_struct { unsigned long buf[100]; };
 
 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
        __asm__ __volatile__(                                           \
+               ASM_STAC"\n"                                            \
                "1:     mov"itype" %2,%"rtype"1\n"                      \
                "2:\n"                                                  \
+               ASM_CLAC"\n"                                            \
                ".section .fixup,\"ax\"\n"                              \
                "3:     mov %3,%0\n"                                    \
                "       xor"itype" %"rtype"1,%"rtype"1\n"               \
diff --git a/xen/include/asm-x86/x86_64/system.h 
b/xen/include/asm-x86/x86_64/system.h
index 20f038b..b8394b9 100644
--- a/xen/include/asm-x86/x86_64/system.h
+++ b/xen/include/asm-x86/x86_64/system.h
@@ -13,8 +13,10 @@
  */
 #define __cmpxchg_user(_p,_o,_n,_isuff,_oppre,_regtype)                 \
     asm volatile (                                                      \
+        ASM_STAC"\n"                                                    \
         "1: lock; cmpxchg"_isuff" %"_oppre"2,%3\n"                      \
         "2:\n"                                                          \
+        ASM_CLAC"\n"                                                    \
         ".section .fixup,\"ax\"\n"                                      \
         "3:     movl $1,%1\n"                                           \
         "       jmp 2b\n"                                               \
-- 
1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.