Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.10697
5b8d5832-x86-assorted-array_index_nospec-insert...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5b8d5832-x86-assorted-array_index_nospec-insertions.patch of Package xen.10697
# Commit 3f2002614af51dfd507168a1696658bac91155ce # Date 2018-09-03 17:50:10 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86: assorted array_index_nospec() insertions Don't chance having Spectre v1 (including BCBS) gadgets. In some of the cases the insertions are more of precautionary nature rather than there provably being a gadget, but I think we should err on the safe (secure) side here. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -31,6 +31,7 @@ #include <xen/domain_page.h> #include <xen/hypercall.h> #include <xen/guest_access.h> +#include <xen/nospec.h> #include <xen/event.h> #include <xen/paging.h> #include <xen/cpu.h> @@ -3898,9 +3899,16 @@ int hvm_do_hypercall(struct cpu_user_reg if ( (eax & 0x80000000) && is_viridian_domain(curr->domain) ) return viridian_hypercall(regs); - if ( (eax >= NR_hypercalls) || - (is_pvh_vcpu(curr) ? !pvh_hypercall64_table[eax] - : !hvm_hypercall32_table[eax]) ) + if ( eax >= NR_hypercalls ) + { + regs->eax = -ENOSYS; + return HVM_HCALL_completed; + } + + eax = array_index_nospec(eax, NR_hypercalls); + + if ( is_pvh_vcpu(curr) ? !pvh_hypercall64_table[eax] + : !hvm_hypercall32_table[eax] ) { regs->eax = -ENOSYS; return HVM_HCALL_completed; @@ -4771,6 +4779,7 @@ long do_hvm_op(unsigned long op, XEN_GUE { struct xen_hvm_set_mem_type a; struct domain *d; + unsigned int mem_type; /* Interface types to internal p2m types */ static const p2m_type_t memtype[] = { @@ -4800,7 +4809,8 @@ long do_hvm_op(unsigned long op, XEN_GUE ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) ) goto param_fail4; - if ( a.hvmmem_type >= ARRAY_SIZE(memtype) ) + mem_type = array_index_nospec(a.hvmmem_type, ARRAY_SIZE(memtype)); + if ( mem_type >= ARRAY_SIZE(memtype) ) goto param_fail4; while ( a.nr ) @@ -4824,21 +4834,21 @@ long do_hvm_op(unsigned long op, XEN_GUE goto param_fail4; } if ( !p2m_is_ram(t) && - (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) ) + (!p2m_is_hole(t) || mem_type != HVMMEM_mmio_dm) ) { put_gfn(d, pfn); goto param_fail4; } else { - nt = p2m_change_type(d, pfn, t, memtype[a.hvmmem_type]); + nt = p2m_change_type(d, pfn, t, memtype[mem_type]); if ( nt != t ) { put_gfn(d, pfn); gdprintk(XENLOG_WARNING, "type of pfn %#lx changed from %d to %d while " "we were trying to change it to %d\n", - pfn, t, nt, memtype[a.hvmmem_type]); + pfn, t, nt, memtype[mem_type]); goto param_fail4; } } --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -30,6 +30,7 @@ #include <asm/p2m.h> #include <asm/hvm/vmx/vmx.h> /* ept_p2m_init() */ #include <xen/iommu.h> +#include <xen/nospec.h> #include <asm/mem_event.h> #include <public/mem_event.h> #include <asm/mem_sharing.h> @@ -1423,6 +1424,7 @@ long p2m_set_mem_access(struct domain *d if ( (unsigned) access >= HVMMEM_access_default ) return -EINVAL; + access = array_index_nospec(access, ARRAY_SIZE(memaccess)); a = memaccess[access]; /* If request to set default access */ --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -31,12 +31,13 @@ UNLIKELY_END(msi_check) cmpl $NR_hypercalls,%eax jae compat_bad_hypercall + sbbl %r8d,%r8d /* array_index_mask_nospec() */ + andl %r8d,%eax #ifndef NDEBUG /* Deliberately corrupt parameter regs not used by this hypercall. */ pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi pushq UREGS_rbp+5*8(%rsp) leaq compat_hypercall_args_table(%rip),%r10 - movl %eax,%eax movl $6,%ecx subb (%r10,%rax,1),%cl movq %rsp,%rdi @@ -51,7 +52,6 @@ UNLIKELY_END(msi_check) #define SHADOW_BYTES 16 /* Shadow EIP + shadow hypercall # */ #else /* Relocate argument registers and zero-extend to 64 bits. */ - movl %eax,%eax /* Hypercall # */ xchgl %ecx,%esi /* Arg 2, Arg 4 */ movl %edx,%edx /* Arg 3 */ movl %edi,%r8d /* Arg 5 */ @@ -61,6 +61,7 @@ UNLIKELY_END(msi_check) #endif cmpb $0,tb_init_done(%rip) UNLIKELY_START(ne, compat_trace) + movl %eax,UREGS_rax+SHADOW_BYTES(%rsp) /* Hypercall # */ call __trace_hypercall_entry /* Restore the registers that __trace_hypercall_entry clobbered. */ movl UREGS_rax+SHADOW_BYTES(%rsp),%eax /* Hypercall # */ --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -210,6 +210,8 @@ ENTRY(syscall_enter) LOAD_C_CLOBBERED cx=0 cmpq $NR_hypercalls,%rax jae bad_hypercall + sbbq %r10,%r10 /* array_index_mask_nospec() */ + andq %r10,%rax #ifndef NDEBUG /* Deliberately corrupt parameter regs not used by this hypercall. */ pushq %rdi; pushq %rsi; pushq %rdx; pushq %rcx; pushq %r8 ; pushq %r9 @@ -229,6 +231,7 @@ ENTRY(syscall_enter) #endif cmpb $0,tb_init_done(%rip) UNLIKELY_START(ne, trace) + movq %rax,UREGS_rax+SHADOW_BYTES(%rsp) /* Hypercall # */ call __trace_hypercall_entry /* Restore the registers that __trace_hypercall_entry clobbered. */ movq UREGS_rax+SHADOW_BYTES(%rsp),%rax /* Hypercall # */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor