All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15 13:01 [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode Feng Wu
@ 2014-04-15  6:08 ` Tian, Kevin
  2014-04-15  6:20   ` Wu, Feng
  2014-04-15  8:46 ` Jan Beulich
  2014-04-15 10:21 ` Andrew Cooper
  2 siblings, 1 reply; 9+ messages in thread
From: Tian, Kevin @ 2014-04-15  6:08 UTC (permalink / raw)
  To: JBeulich@suse.com, Ian.Campbell@citrix.com,
	xen-devel@lists.xen.org
  Cc: Dong, Eddie, Wu, Feng, Nakajima, Jun

> From: Feng Wu
> Sent: Tuesday, April 15, 2014 9:02 PM
> 
> Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
> user pages in kernel mode
> 
> Signed-off-by: Feng Wu <feng.wu@intel.com>
> ---
>  xen/arch/x86/clear_page.S           |  3 +++
>  xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
>  xen/arch/x86/usercopy.c             |  6 ++++++
>  xen/arch/x86/x86_64/compat/entry.S  |  2 ++
>  xen/arch/x86/x86_64/entry.S         |  4 ++++
>  xen/include/asm-x86/uaccess.h       |  4 ++++
>  xen/include/asm-x86/x86_64/system.h |  2 ++
>  7 files changed, 37 insertions(+)
> 
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index 84ce392..1ba138b 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -789,8 +789,10 @@ int __init construct_dom0(
>              rc = -1;
>              goto out;
>          }
> +        stac();
>          hypercall_page_initialise(
>              d, (void *)(unsigned long)parms.virt_hypercall);
> +        clac();
>      }

construct_dom0 happens before dom0 starts execution. It should be fine to
keep AC cleared in the whole phase.

Thanks
Kevin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15  6:08 ` Tian, Kevin
@ 2014-04-15  6:20   ` Wu, Feng
  2014-04-15  6:35     ` Tian, Kevin
  0 siblings, 1 reply; 9+ messages in thread
From: Wu, Feng @ 2014-04-15  6:20 UTC (permalink / raw)
  To: Tian, Kevin, JBeulich@suse.com, Ian.Campbell@citrix.com,
	xen-devel@lists.xen.org
  Cc: Dong, Eddie, Nakajima, Jun



> -----Original Message-----
> From: Tian, Kevin
> Sent: Tuesday, April 15, 2014 2:08 PM
> To: Wu, Feng; JBeulich@suse.com; Ian.Campbell@citrix.com;
> xen-devel@lists.xen.org
> Cc: Wu, Feng; Dong, Eddie; Nakajima, Jun
> Subject: RE: [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to legally
> access user pages in kernel mode
> 
> > From: Feng Wu
> > Sent: Tuesday, April 15, 2014 9:02 PM
> >
> > Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
> > user pages in kernel mode
> >
> > Signed-off-by: Feng Wu <feng.wu@intel.com>
> > ---
> >  xen/arch/x86/clear_page.S           |  3 +++
> >  xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
> >  xen/arch/x86/usercopy.c             |  6 ++++++
> >  xen/arch/x86/x86_64/compat/entry.S  |  2 ++
> >  xen/arch/x86/x86_64/entry.S         |  4 ++++
> >  xen/include/asm-x86/uaccess.h       |  4 ++++
> >  xen/include/asm-x86/x86_64/system.h |  2 ++
> >  7 files changed, 37 insertions(+)
> >
> > diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> > index 84ce392..1ba138b 100644
> > --- a/xen/arch/x86/domain_build.c
> > +++ b/xen/arch/x86/domain_build.c
> > @@ -789,8 +789,10 @@ int __init construct_dom0(
> >              rc = -1;
> >              goto out;
> >          }
> > +        stac();
> >          hypercall_page_initialise(
> >              d, (void *)(unsigned long)parms.virt_hypercall);
> > +        clac();
> >      }
> 
> construct_dom0 happens before dom0 starts execution. It should be fine to
> keep AC cleared in the whole phase.

construct_dom0() accesses user pages in the supervisor mode, so I added the stac()/clac()
one by one, otherwise, Xen hypervisor will receive an SMAP violation.

> 
> Thanks
> Kevin

Thanks,
Feng

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15  6:20   ` Wu, Feng
@ 2014-04-15  6:35     ` Tian, Kevin
  2014-04-15  6:53       ` Wu, Feng
  0 siblings, 1 reply; 9+ messages in thread
From: Tian, Kevin @ 2014-04-15  6:35 UTC (permalink / raw)
  To: Wu, Feng, JBeulich@suse.com, Ian.Campbell@citrix.com,
	xen-devel@lists.xen.org
  Cc: Dong, Eddie, Nakajima, Jun

> From: Wu, Feng
> Sent: Tuesday, April 15, 2014 2:21 PM
> 
> > -----Original Message-----
> > From: Tian, Kevin
> > Sent: Tuesday, April 15, 2014 2:08 PM
> > To: Wu, Feng; JBeulich@suse.com; Ian.Campbell@citrix.com;
> > xen-devel@lists.xen.org
> > Cc: Wu, Feng; Dong, Eddie; Nakajima, Jun
> > Subject: RE: [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to
> legally
> > access user pages in kernel mode
> >
> > > From: Feng Wu
> > > Sent: Tuesday, April 15, 2014 9:02 PM
> > >
> > > Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
> > > user pages in kernel mode
> > >
> > > Signed-off-by: Feng Wu <feng.wu@intel.com>
> > > ---
> > >  xen/arch/x86/clear_page.S           |  3 +++
> > >  xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
> > >  xen/arch/x86/usercopy.c             |  6 ++++++
> > >  xen/arch/x86/x86_64/compat/entry.S  |  2 ++
> > >  xen/arch/x86/x86_64/entry.S         |  4 ++++
> > >  xen/include/asm-x86/uaccess.h       |  4 ++++
> > >  xen/include/asm-x86/x86_64/system.h |  2 ++
> > >  7 files changed, 37 insertions(+)
> > >
> > > diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> > > index 84ce392..1ba138b 100644
> > > --- a/xen/arch/x86/domain_build.c
> > > +++ b/xen/arch/x86/domain_build.c
> > > @@ -789,8 +789,10 @@ int __init construct_dom0(
> > >              rc = -1;
> > >              goto out;
> > >          }
> > > +        stac();
> > >          hypercall_page_initialise(
> > >              d, (void *)(unsigned long)parms.virt_hypercall);
> > > +        clac();
> > >      }
> >
> > construct_dom0 happens before dom0 starts execution. It should be fine to
> > keep AC cleared in the whole phase.
> 
> construct_dom0() accesses user pages in the supervisor mode, so I added the
> stac()/clac()
> one by one, otherwise, Xen hypervisor will receive an SMAP violation.
> 

I meant you can do once to enable user page accesses, and then disable it
at end of construct_dom0. There should be no security concern at this stage.

Thanks
Kevin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15  6:35     ` Tian, Kevin
@ 2014-04-15  6:53       ` Wu, Feng
  0 siblings, 0 replies; 9+ messages in thread
From: Wu, Feng @ 2014-04-15  6:53 UTC (permalink / raw)
  To: Tian, Kevin, JBeulich@suse.com, Ian.Campbell@citrix.com,
	xen-devel@lists.xen.org
  Cc: Dong, Eddie, Nakajima, Jun



> -----Original Message-----
> From: Tian, Kevin
> Sent: Tuesday, April 15, 2014 2:36 PM
> To: Wu, Feng; JBeulich@suse.com; Ian.Campbell@citrix.com;
> xen-devel@lists.xen.org
> Cc: Dong, Eddie; Nakajima, Jun
> Subject: RE: [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to legally
> access user pages in kernel mode
> 
> > From: Wu, Feng
> > Sent: Tuesday, April 15, 2014 2:21 PM
> >
> > > -----Original Message-----
> > > From: Tian, Kevin
> > > Sent: Tuesday, April 15, 2014 2:08 PM
> > > To: Wu, Feng; JBeulich@suse.com; Ian.Campbell@citrix.com;
> > > xen-devel@lists.xen.org
> > > Cc: Wu, Feng; Dong, Eddie; Nakajima, Jun
> > > Subject: RE: [Xen-devel] [PATCH v1 2/6] x86: Temporary disable SMAP to
> > legally
> > > access user pages in kernel mode
> > >
> > > > From: Feng Wu
> > > > Sent: Tuesday, April 15, 2014 9:02 PM
> > > >
> > > > Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
> > > > user pages in kernel mode
> > > >
> > > > Signed-off-by: Feng Wu <feng.wu@intel.com>
> > > > ---
> > > >  xen/arch/x86/clear_page.S           |  3 +++
> > > >  xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
> > > >  xen/arch/x86/usercopy.c             |  6 ++++++
> > > >  xen/arch/x86/x86_64/compat/entry.S  |  2 ++
> > > >  xen/arch/x86/x86_64/entry.S         |  4 ++++
> > > >  xen/include/asm-x86/uaccess.h       |  4 ++++
> > > >  xen/include/asm-x86/x86_64/system.h |  2 ++
> > > >  7 files changed, 37 insertions(+)
> > > >
> > > > diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> > > > index 84ce392..1ba138b 100644
> > > > --- a/xen/arch/x86/domain_build.c
> > > > +++ b/xen/arch/x86/domain_build.c
> > > > @@ -789,8 +789,10 @@ int __init construct_dom0(
> > > >              rc = -1;
> > > >              goto out;
> > > >          }
> > > > +        stac();
> > > >          hypercall_page_initialise(
> > > >              d, (void *)(unsigned long)parms.virt_hypercall);
> > > > +        clac();
> > > >      }
> > >
> > > construct_dom0 happens before dom0 starts execution. It should be fine to
> > > keep AC cleared in the whole phase.
> >
> > construct_dom0() accesses user pages in the supervisor mode, so I added the
> > stac()/clac()
> > one by one, otherwise, Xen hypervisor will receive an SMAP violation.
> >
> 
> I meant you can do once to enable user page accesses, and then disable it
> at end of construct_dom0. There should be no security concern at this stage.

Yes, that is a clean solution. I also thought about it before, but I was not sure whether
there was security issues with it. As you said, if there is no security concern, your
suggestion is better for sure.

> 
> Thanks
> Kevin

Thanks,
Feng

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15 13:01 [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode Feng Wu
  2014-04-15  6:08 ` Tian, Kevin
@ 2014-04-15  8:46 ` Jan Beulich
  2014-04-16  6:14   ` Wu, Feng
  2014-04-15 10:21 ` Andrew Cooper
  2 siblings, 1 reply; 9+ messages in thread
From: Jan Beulich @ 2014-04-15  8:46 UTC (permalink / raw)
  To: Feng Wu; +Cc: eddie.dong, Ian.Campbell, jun.nakajima, xen-devel

>>> On 15.04.14 at 15:01, <feng.wu@intel.com> wrote:
> --- a/xen/arch/x86/clear_page.S
> +++ b/xen/arch/x86/clear_page.S
> @@ -1,9 +1,11 @@
>  #include <xen/config.h>
>  #include <asm/page.h>
> +#include <asm/asm_defns.h>
>  
>  #define ptr_reg %rdi
>  
>  ENTRY(clear_page_sse2)
> +        ASM_STAC
>          mov     $PAGE_SIZE/16, %ecx
>          xor     %eax,%eax
>  
> @@ -15,5 +17,6 @@ ENTRY(clear_page_sse2)
>          lea     16(ptr_reg), ptr_reg
>          jnz     0b
>  
> +        ASM_CLAC
>          sfence
>          ret

Wrong code being modified - this isn't used to clear guest memory (or
else we have a security problem). If there are pages having the U bit
set, then I guess you need to first go and clean those up.

> --- a/xen/arch/x86/x86_64/compat/entry.S
> +++ b/xen/arch/x86/x86_64/compat/entry.S
> @@ -265,6 +265,7 @@ ENTRY(compat_int80_direct_trap)
>  /* On return only %rbx and %rdx are guaranteed non-clobbered.            */
>  compat_create_bounce_frame:
>          ASSERT_INTERRUPTS_ENABLED
> +        ASM_STAC
>          mov   %fs,%edi
>          testb $2,UREGS_cs+8(%rsp)
>          jz    1f
> @@ -336,6 +337,7 @@ __UNLIKELY_END(compat_bounce_null_selector)
>          movl  %eax,UREGS_cs+8(%rsp)
>          movl  TRAPBOUNCE_eip(%rdx),%eax
>          movl  %eax,UREGS_rip+8(%rsp)
> +        ASM_CLAC
>          ret

These and the similar changes to xen/arch/x86/x86_64/entry.S seem
pretty pointless without also  adding ASM_CLAC to the exception and
interrupt entry points.

Jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15 13:01 [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode Feng Wu
  2014-04-15  6:08 ` Tian, Kevin
  2014-04-15  8:46 ` Jan Beulich
@ 2014-04-15 10:21 ` Andrew Cooper
  2014-04-15 10:31   ` Jan Beulich
  2 siblings, 1 reply; 9+ messages in thread
From: Andrew Cooper @ 2014-04-15 10:21 UTC (permalink / raw)
  To: Feng Wu; +Cc: jun.nakajima, eddie.dong, Ian.Campbell, JBeulich, xen-devel

On 15/04/14 14:01, Feng Wu wrote:
> Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
> user pages in kernel mode
>
> Signed-off-by: Feng Wu <feng.wu@intel.com>
> ---
>  xen/arch/x86/clear_page.S           |  3 +++
>  xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
>  xen/arch/x86/usercopy.c             |  6 ++++++
>  xen/arch/x86/x86_64/compat/entry.S  |  2 ++
>  xen/arch/x86/x86_64/entry.S         |  4 ++++
>  xen/include/asm-x86/uaccess.h       |  4 ++++
>  xen/include/asm-x86/x86_64/system.h |  2 ++
>  7 files changed, 37 insertions(+)
>
> diff --git a/xen/arch/x86/clear_page.S b/xen/arch/x86/clear_page.S
> index 96315ad..2ef4bb0 100644
> --- a/xen/arch/x86/clear_page.S
> +++ b/xen/arch/x86/clear_page.S
> @@ -1,9 +1,11 @@
>  #include <xen/config.h>
>  #include <asm/page.h>
> +#include <asm/asm_defns.h>
>  
>  #define ptr_reg %rdi
>  
>  ENTRY(clear_page_sse2)
> +        ASM_STAC
>          mov     $PAGE_SIZE/16, %ecx
>          xor     %eax,%eax
>  
> @@ -15,5 +17,6 @@ ENTRY(clear_page_sse2)
>          lea     16(ptr_reg), ptr_reg
>          jnz     0b
>  
> +        ASM_CLAC
>          sfence
>          ret
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index 84ce392..1ba138b 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -789,8 +789,10 @@ int __init construct_dom0(
>              rc = -1;
>              goto out;
>          }
> +        stac();
>          hypercall_page_initialise(
>              d, (void *)(unsigned long)parms.virt_hypercall);
> +        clac();
>      }
>  
>      /* Free temporary buffers. */
> @@ -799,6 +801,7 @@ int __init construct_dom0(
>      /* Set up start info area. */
>      si = (start_info_t *)vstartinfo_start;
>      clear_page(si);
> +    stac();
>      si->nr_pages = nr_pages;
>  
>      si->shared_info = virt_to_maddr(d->shared_info);
> @@ -813,6 +816,7 @@ int __init construct_dom0(
>      snprintf(si->magic, sizeof(si->magic), "xen-3.0-x86_%d%s",
>               elf_64bit(&elf) ? 64 : 32, parms.pae ? "p" : "");
>  
> +    clac();
>      count = d->tot_pages;
>      l4start = map_domain_page(pagetable_get_pfn(v->arch.guest_table));
>      l3tab = NULL;
> @@ -956,16 +960,20 @@ int __init construct_dom0(
>          if ( pfn > REVERSE_START && (vinitrd_start || pfn < initrd_pfn) )
>              mfn = alloc_epfn - (pfn - REVERSE_START);
>  #endif
> +        stac();
>          if ( !is_pv_32on64_domain(d) )
>              ((unsigned long *)vphysmap_start)[pfn] = mfn;
>          else
>              ((unsigned int *)vphysmap_start)[pfn] = mfn;
> +        clac();
>          set_gpfn_from_mfn(mfn, pfn);
>          if (!(pfn & 0xfffff))
>              process_pending_softirqs();
>      }
> +    stac();
>      si->first_p2m_pfn = pfn;
>      si->nr_p2m_frames = d->tot_pages - count;
> +    clac();
>      page_list_for_each ( page, &d->page_list )
>      {
>          mfn = page_to_mfn(page);
> @@ -976,7 +984,9 @@ int __init construct_dom0(
>              if ( !page->u.inuse.type_info &&
>                   !get_page_and_type(page, d, PGT_writable_page) )
>                  BUG();
> +            stac();
>              ((unsigned long *)vphysmap_start)[pfn] = mfn;
> +            clac();
>              set_gpfn_from_mfn(mfn, pfn);
>              ++pfn;
>              if (!(pfn & 0xfffff))
> @@ -985,7 +995,9 @@ int __init construct_dom0(
>      }
>      BUG_ON(pfn != d->tot_pages);
>  #ifndef NDEBUG
> +    stac();
>      alloc_epfn += PFN_UP(initrd_len) + si->nr_p2m_frames;
> +    clac();

This could presumably be eliminated by keeping a stack copy of
si->nr_p2m_frames ?

~Andrew

>  #endif
>      while ( pfn < nr_pages )
>      {
> @@ -997,10 +1009,12 @@ int __init construct_dom0(
>  #ifndef NDEBUG
>  #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn)))
>  #endif
> +            stac();
>              if ( !is_pv_32on64_domain(d) )
>                  ((unsigned long *)vphysmap_start)[pfn] = mfn;
>              else
>                  ((unsigned int *)vphysmap_start)[pfn] = mfn;
> +            clac();
>              set_gpfn_from_mfn(mfn, pfn);
>  #undef pfn
>              page++; pfn++;
> @@ -1009,6 +1023,7 @@ int __init construct_dom0(
>          }
>      }
>  
> +    stac();
>      if ( initrd_len != 0 )
>      {
>          si->mod_start = vinitrd_start ?: initrd_pfn;
> @@ -1024,6 +1039,7 @@ int __init construct_dom0(
>          si->console.dom0.info_off  = sizeof(struct start_info);
>          si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
>      }
> +    clac();
>  
>      if ( is_pv_32on64_domain(d) )
>          xlat_start_info(si, XLAT_start_info_console_dom0);
> diff --git a/xen/arch/x86/usercopy.c b/xen/arch/x86/usercopy.c
> index b79202b..5dd77db 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/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
> index 32b3bcc..b0fabf4 100644
> --- a/xen/arch/x86/x86_64/compat/entry.S
> +++ b/xen/arch/x86/x86_64/compat/entry.S
> @@ -265,6 +265,7 @@ ENTRY(compat_int80_direct_trap)
>  /* On return only %rbx and %rdx are guaranteed non-clobbered.            */
>  compat_create_bounce_frame:
>          ASSERT_INTERRUPTS_ENABLED
> +        ASM_STAC
>          mov   %fs,%edi
>          testb $2,UREGS_cs+8(%rsp)
>          jz    1f
> @@ -336,6 +337,7 @@ __UNLIKELY_END(compat_bounce_null_selector)
>          movl  %eax,UREGS_cs+8(%rsp)
>          movl  TRAPBOUNCE_eip(%rdx),%eax
>          movl  %eax,UREGS_rip+8(%rsp)
> +        ASM_CLAC
>          ret
>  .section .fixup,"ax"
>  .Lfx13:
> diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
> index 3ea4683..63ba795 100644
> --- a/xen/arch/x86/x86_64/entry.S
> +++ b/xen/arch/x86/x86_64/entry.S
> @@ -377,6 +377,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
> @@ -434,9 +435,11 @@ UNLIKELY_END(bounce_failsafe)
>          testq %rax,%rax
>  UNLIKELY_START(z, create_bounce_frame_bad_bounce_ip)
>          lea   UNLIKELY_DISPATCH_LABEL(create_bounce_frame_bad_bounce_ip)(%rip), %rdi
> +        ASM_CLAC
>          jmp   asm_domain_crash_synchronous  /* Does not return */
>  __UNLIKELY_END(create_bounce_frame_bad_bounce_ip)
>          movq  %rax,UREGS_rip+8(%rsp)
> +        ASM_CLAC
>          ret
>          _ASM_EXTABLE(.Lft2,  dom_crash_sync_extable)
>          _ASM_EXTABLE(.Lft3,  dom_crash_sync_extable)
> @@ -463,6 +466,7 @@ ENTRY(dom_crash_sync_extable)
>          leal  (%rax,%rax,2),%eax
>          orb   %al,UREGS_cs(%rsp)
>          xorl  %edi,%edi
> +        ASM_CLAC
>          jmp   asm_domain_crash_synchronous /* Does not return */
>  
>  /* No special register assumptions. */
> 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"                                               \

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15 10:21 ` Andrew Cooper
@ 2014-04-15 10:31   ` Jan Beulich
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Beulich @ 2014-04-15 10:31 UTC (permalink / raw)
  To: Andrew Cooper, Feng Wu; +Cc: eddie.dong, Ian.Campbell, jun.nakajima, xen-devel

>>> On 15.04.14 at 12:21, <andrew.cooper3@citrix.com> wrote:
> On 15/04/14 14:01, Feng Wu wrote:
>> @@ -985,7 +995,9 @@ int __init construct_dom0(
>>      }
>>      BUG_ON(pfn != d->tot_pages);
>>  #ifndef NDEBUG
>> +    stac();
>>      alloc_epfn += PFN_UP(initrd_len) + si->nr_p2m_frames;
>> +    clac();
> 
> This could presumably be eliminated by keeping a stack copy of
> si->nr_p2m_frames ?

That'll go away together with everything else here in favor of
construct_dom0() as a whole getting wrapped in a stac()/clac()
part (as suggested by Kevin).

Jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
@ 2014-04-15 13:01 Feng Wu
  2014-04-15  6:08 ` Tian, Kevin
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Feng Wu @ 2014-04-15 13:01 UTC (permalink / raw)
  To: JBeulich, Ian.Campbell, xen-devel; +Cc: Feng Wu, eddie.dong, jun.nakajima

Use STAC/CLAC to temporary disable SMAP to allow legal accesses to
user pages in kernel mode

Signed-off-by: Feng Wu <feng.wu@intel.com>
---
 xen/arch/x86/clear_page.S           |  3 +++
 xen/arch/x86/domain_build.c         | 16 ++++++++++++++++
 xen/arch/x86/usercopy.c             |  6 ++++++
 xen/arch/x86/x86_64/compat/entry.S  |  2 ++
 xen/arch/x86/x86_64/entry.S         |  4 ++++
 xen/include/asm-x86/uaccess.h       |  4 ++++
 xen/include/asm-x86/x86_64/system.h |  2 ++
 7 files changed, 37 insertions(+)

diff --git a/xen/arch/x86/clear_page.S b/xen/arch/x86/clear_page.S
index 96315ad..2ef4bb0 100644
--- a/xen/arch/x86/clear_page.S
+++ b/xen/arch/x86/clear_page.S
@@ -1,9 +1,11 @@
 #include <xen/config.h>
 #include <asm/page.h>
+#include <asm/asm_defns.h>
 
 #define ptr_reg %rdi
 
 ENTRY(clear_page_sse2)
+        ASM_STAC
         mov     $PAGE_SIZE/16, %ecx
         xor     %eax,%eax
 
@@ -15,5 +17,6 @@ ENTRY(clear_page_sse2)
         lea     16(ptr_reg), ptr_reg
         jnz     0b
 
+        ASM_CLAC
         sfence
         ret
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 84ce392..1ba138b 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -789,8 +789,10 @@ int __init construct_dom0(
             rc = -1;
             goto out;
         }
+        stac();
         hypercall_page_initialise(
             d, (void *)(unsigned long)parms.virt_hypercall);
+        clac();
     }
 
     /* Free temporary buffers. */
@@ -799,6 +801,7 @@ int __init construct_dom0(
     /* Set up start info area. */
     si = (start_info_t *)vstartinfo_start;
     clear_page(si);
+    stac();
     si->nr_pages = nr_pages;
 
     si->shared_info = virt_to_maddr(d->shared_info);
@@ -813,6 +816,7 @@ int __init construct_dom0(
     snprintf(si->magic, sizeof(si->magic), "xen-3.0-x86_%d%s",
              elf_64bit(&elf) ? 64 : 32, parms.pae ? "p" : "");
 
+    clac();
     count = d->tot_pages;
     l4start = map_domain_page(pagetable_get_pfn(v->arch.guest_table));
     l3tab = NULL;
@@ -956,16 +960,20 @@ int __init construct_dom0(
         if ( pfn > REVERSE_START && (vinitrd_start || pfn < initrd_pfn) )
             mfn = alloc_epfn - (pfn - REVERSE_START);
 #endif
+        stac();
         if ( !is_pv_32on64_domain(d) )
             ((unsigned long *)vphysmap_start)[pfn] = mfn;
         else
             ((unsigned int *)vphysmap_start)[pfn] = mfn;
+        clac();
         set_gpfn_from_mfn(mfn, pfn);
         if (!(pfn & 0xfffff))
             process_pending_softirqs();
     }
+    stac();
     si->first_p2m_pfn = pfn;
     si->nr_p2m_frames = d->tot_pages - count;
+    clac();
     page_list_for_each ( page, &d->page_list )
     {
         mfn = page_to_mfn(page);
@@ -976,7 +984,9 @@ int __init construct_dom0(
             if ( !page->u.inuse.type_info &&
                  !get_page_and_type(page, d, PGT_writable_page) )
                 BUG();
+            stac();
             ((unsigned long *)vphysmap_start)[pfn] = mfn;
+            clac();
             set_gpfn_from_mfn(mfn, pfn);
             ++pfn;
             if (!(pfn & 0xfffff))
@@ -985,7 +995,9 @@ int __init construct_dom0(
     }
     BUG_ON(pfn != d->tot_pages);
 #ifndef NDEBUG
+    stac();
     alloc_epfn += PFN_UP(initrd_len) + si->nr_p2m_frames;
+    clac();
 #endif
     while ( pfn < nr_pages )
     {
@@ -997,10 +1009,12 @@ int __init construct_dom0(
 #ifndef NDEBUG
 #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn)))
 #endif
+            stac();
             if ( !is_pv_32on64_domain(d) )
                 ((unsigned long *)vphysmap_start)[pfn] = mfn;
             else
                 ((unsigned int *)vphysmap_start)[pfn] = mfn;
+            clac();
             set_gpfn_from_mfn(mfn, pfn);
 #undef pfn
             page++; pfn++;
@@ -1009,6 +1023,7 @@ int __init construct_dom0(
         }
     }
 
+    stac();
     if ( initrd_len != 0 )
     {
         si->mod_start = vinitrd_start ?: initrd_pfn;
@@ -1024,6 +1039,7 @@ int __init construct_dom0(
         si->console.dom0.info_off  = sizeof(struct start_info);
         si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
     }
+    clac();
 
     if ( is_pv_32on64_domain(d) )
         xlat_start_info(si, XLAT_start_info_console_dom0);
diff --git a/xen/arch/x86/usercopy.c b/xen/arch/x86/usercopy.c
index b79202b..5dd77db 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/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index 32b3bcc..b0fabf4 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -265,6 +265,7 @@ ENTRY(compat_int80_direct_trap)
 /* On return only %rbx and %rdx are guaranteed non-clobbered.            */
 compat_create_bounce_frame:
         ASSERT_INTERRUPTS_ENABLED
+        ASM_STAC
         mov   %fs,%edi
         testb $2,UREGS_cs+8(%rsp)
         jz    1f
@@ -336,6 +337,7 @@ __UNLIKELY_END(compat_bounce_null_selector)
         movl  %eax,UREGS_cs+8(%rsp)
         movl  TRAPBOUNCE_eip(%rdx),%eax
         movl  %eax,UREGS_rip+8(%rsp)
+        ASM_CLAC
         ret
 .section .fixup,"ax"
 .Lfx13:
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 3ea4683..63ba795 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -377,6 +377,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
@@ -434,9 +435,11 @@ UNLIKELY_END(bounce_failsafe)
         testq %rax,%rax
 UNLIKELY_START(z, create_bounce_frame_bad_bounce_ip)
         lea   UNLIKELY_DISPATCH_LABEL(create_bounce_frame_bad_bounce_ip)(%rip), %rdi
+        ASM_CLAC
         jmp   asm_domain_crash_synchronous  /* Does not return */
 __UNLIKELY_END(create_bounce_frame_bad_bounce_ip)
         movq  %rax,UREGS_rip+8(%rsp)
+        ASM_CLAC
         ret
         _ASM_EXTABLE(.Lft2,  dom_crash_sync_extable)
         _ASM_EXTABLE(.Lft3,  dom_crash_sync_extable)
@@ -463,6 +466,7 @@ ENTRY(dom_crash_sync_extable)
         leal  (%rax,%rax,2),%eax
         orb   %al,UREGS_cs(%rsp)
         xorl  %edi,%edi
+        ASM_CLAC
         jmp   asm_domain_crash_synchronous /* Does not return */
 
 /* No special register assumptions. */
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

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode
  2014-04-15  8:46 ` Jan Beulich
@ 2014-04-16  6:14   ` Wu, Feng
  0 siblings, 0 replies; 9+ messages in thread
From: Wu, Feng @ 2014-04-16  6:14 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Dong, Eddie, Ian.Campbell@citrix.com, Nakajima, Jun,
	xen-devel@lists.xen.org



> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, April 15, 2014 4:47 PM
> To: Wu, Feng
> Cc: Ian.Campbell@citrix.com; Dong, Eddie; Nakajima, Jun;
> xen-devel@lists.xen.org
> Subject: Re: [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user
> pages in kernel mode
> 
> >>> On 15.04.14 at 15:01, <feng.wu@intel.com> wrote:
> > --- a/xen/arch/x86/clear_page.S
> > +++ b/xen/arch/x86/clear_page.S
> > @@ -1,9 +1,11 @@
> >  #include <xen/config.h>
> >  #include <asm/page.h>
> > +#include <asm/asm_defns.h>
> >
> >  #define ptr_reg %rdi
> >
> >  ENTRY(clear_page_sse2)
> > +        ASM_STAC
> >          mov     $PAGE_SIZE/16, %ecx
> >          xor     %eax,%eax
> >
> > @@ -15,5 +17,6 @@ ENTRY(clear_page_sse2)
> >          lea     16(ptr_reg), ptr_reg
> >          jnz     0b
> >
> > +        ASM_CLAC
> >          sfence
> >          ret
> 
> Wrong code being modified - this isn't used to clear guest memory (or
> else we have a security problem). If there are pages having the U bit
> set, then I guess you need to first go and clean those up.

I got an SMAP violation in function clear_page_sse2() while debugging,
which makes me think that this function accesses user pages and the AC
bit needs to be set. However, today I find that the real fault happens in
construct_dom0() like the following code path. After adopt Kevin's suggestion,
we will make construct_dom0() wrapped in a stac()/clac() part as a whole. 
So the changes here should be removed. Thanks for your comments!

__start_xen() --> construct_dom0() --> clear_page() --> clear_page_sse2()

> 
> > --- a/xen/arch/x86/x86_64/compat/entry.S
> > +++ b/xen/arch/x86/x86_64/compat/entry.S
> > @@ -265,6 +265,7 @@ ENTRY(compat_int80_direct_trap)
> >  /* On return only %rbx and %rdx are guaranteed non-clobbered.
> */
> >  compat_create_bounce_frame:
> >          ASSERT_INTERRUPTS_ENABLED
> > +        ASM_STAC
> >          mov   %fs,%edi
> >          testb $2,UREGS_cs+8(%rsp)
> >          jz    1f
> > @@ -336,6 +337,7 @@ __UNLIKELY_END(compat_bounce_null_selector)
> >          movl  %eax,UREGS_cs+8(%rsp)
> >          movl  TRAPBOUNCE_eip(%rdx),%eax
> >          movl  %eax,UREGS_rip+8(%rsp)
> > +        ASM_CLAC
> >          ret
> 
> These and the similar changes to xen/arch/x86/x86_64/entry.S seem
> pretty pointless without also  adding ASM_CLAC to the exception and
> interrupt entry points.
> 
Yes, you are right, we should add ASM_CLAC in those places! Thanks a lot!

> Jan

Thanks,
Feng

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-04-16  6:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-15 13:01 [PATCH v1 2/6] x86: Temporary disable SMAP to legally access user pages in kernel mode Feng Wu
2014-04-15  6:08 ` Tian, Kevin
2014-04-15  6:20   ` Wu, Feng
2014-04-15  6:35     ` Tian, Kevin
2014-04-15  6:53       ` Wu, Feng
2014-04-15  8:46 ` Jan Beulich
2014-04-16  6:14   ` Wu, Feng
2014-04-15 10:21 ` Andrew Cooper
2014-04-15 10:31   ` Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.