mirror of
https://github.com/Ponce/slackbuilds
synced 2024-11-22 19:44:21 +01:00
system/xen: Added XSA-190 security advisory patch.
Signed-off-by: Mario Preksavec <mario@slackware.hr>
This commit is contained in:
parent
0fa1762f09
commit
b1a0ce4079
2 changed files with 174 additions and 1 deletions
|
@ -24,7 +24,7 @@
|
|||
|
||||
PRGNAM=xen
|
||||
VERSION=${VERSION:-4.7.0}
|
||||
BUILD=${BUILD:-1}
|
||||
BUILD=${BUILD:-2}
|
||||
TAG=${TAG:-_SBo}
|
||||
|
||||
SEABIOS=${SEABIOS:-1.9.2}
|
||||
|
|
173
system/xen/xsa/xsa190.patch
Normal file
173
system/xen/xsa/xsa190.patch
Normal file
|
@ -0,0 +1,173 @@
|
|||
x86emul: honor guest CR0.TS and CR0.EM
|
||||
|
||||
We must not emulate any instructions accessing respective registers
|
||||
when either of these flags is set in the guest view of the register, or
|
||||
else we may do so on data not belonging to the guest's current task.
|
||||
|
||||
Being architecturally required behavior, the logic gets placed in the
|
||||
instruction emulator instead of hvmemul_get_fpu(). It should be noted,
|
||||
though, that hvmemul_get_fpu() being the only current handler for the
|
||||
get_fpu() callback, we don't have an active problem with CR4: Both
|
||||
CR4.OSFXSR and CR4.OSXSAVE get handled as necessary by that function.
|
||||
|
||||
This is XSA-190.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
---
|
||||
v4: Only raise #NM on FWAIT when CR0.TS and CR0.MP are set.
|
||||
v3: Correct which exception to raise upon set CR0.EM.
|
||||
v2: Require the read_cr hook to be set, which then requires a change to
|
||||
the test code too.
|
||||
---
|
||||
The change to xen/arch/x86/hvm/emulate.c isn't strictly needed for
|
||||
fixing the security issue, but the patch would be rather incomplete
|
||||
without.
|
||||
|
||||
--- a/tools/tests/x86_emulator/test_x86_emulator.c
|
||||
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
|
||||
@@ -158,6 +158,22 @@ static inline uint64_t xgetbv(uint32_t x
|
||||
(ebx & (1U << 5)) != 0; \
|
||||
})
|
||||
|
||||
+static int read_cr(
|
||||
+ unsigned int reg,
|
||||
+ unsigned long *val,
|
||||
+ struct x86_emulate_ctxt *ctxt)
|
||||
+{
|
||||
+ /* Fake just enough state for the emulator's _get_fpu() to be happy. */
|
||||
+ switch ( reg )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ *val = 0x00000001; /* PE */
|
||||
+ return X86EMUL_OKAY;
|
||||
+ }
|
||||
+
|
||||
+ return X86EMUL_UNHANDLEABLE;
|
||||
+}
|
||||
+
|
||||
int get_fpu(
|
||||
void (*exception_callback)(void *, struct cpu_user_regs *),
|
||||
void *exception_callback_arg,
|
||||
@@ -189,6 +205,7 @@ static struct x86_emulate_ops emulops =
|
||||
.write = write,
|
||||
.cmpxchg = cmpxchg,
|
||||
.cpuid = cpuid,
|
||||
+ .read_cr = read_cr,
|
||||
.get_fpu = get_fpu,
|
||||
};
|
||||
|
||||
--- a/xen/arch/x86/hvm/emulate.c
|
||||
+++ b/xen/arch/x86/hvm/emulate.c
|
||||
@@ -1628,14 +1628,14 @@ static int hvmemul_get_fpu(
|
||||
switch ( type )
|
||||
{
|
||||
case X86EMUL_FPU_fpu:
|
||||
+ case X86EMUL_FPU_wait:
|
||||
break;
|
||||
case X86EMUL_FPU_mmx:
|
||||
if ( !cpu_has_mmx )
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
break;
|
||||
case X86EMUL_FPU_xmm:
|
||||
- if ( (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_EM) ||
|
||||
- !(curr->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSFXSR) )
|
||||
+ if ( !(curr->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSFXSR) )
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
break;
|
||||
case X86EMUL_FPU_ymm:
|
||||
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
@@ -420,6 +420,9 @@ typedef union {
|
||||
|
||||
/* Control register flags. */
|
||||
#define CR0_PE (1<<0)
|
||||
+#define CR0_MP (1<<1)
|
||||
+#define CR0_EM (1<<2)
|
||||
+#define CR0_TS (1<<3)
|
||||
#define CR4_TSD (1<<2)
|
||||
|
||||
/* EFLAGS bit definitions. */
|
||||
@@ -447,6 +450,7 @@ typedef union {
|
||||
#define EXC_OF 4
|
||||
#define EXC_BR 5
|
||||
#define EXC_UD 6
|
||||
+#define EXC_NM 7
|
||||
#define EXC_TS 10
|
||||
#define EXC_NP 11
|
||||
#define EXC_SS 12
|
||||
@@ -746,10 +750,45 @@ static void fpu_handle_exception(void *_
|
||||
regs->eip += fic->insn_bytes;
|
||||
}
|
||||
|
||||
+static int _get_fpu(
|
||||
+ enum x86_emulate_fpu_type type,
|
||||
+ struct fpu_insn_ctxt *fic,
|
||||
+ struct x86_emulate_ctxt *ctxt,
|
||||
+ const struct x86_emulate_ops *ops)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ fic->exn_raised = 0;
|
||||
+
|
||||
+ fail_if(!ops->get_fpu);
|
||||
+ rc = ops->get_fpu(fpu_handle_exception, fic, type, ctxt);
|
||||
+
|
||||
+ if ( rc == X86EMUL_OKAY )
|
||||
+ {
|
||||
+ unsigned long cr0;
|
||||
+
|
||||
+ fail_if(!ops->read_cr);
|
||||
+ rc = ops->read_cr(0, &cr0, ctxt);
|
||||
+ if ( rc != X86EMUL_OKAY )
|
||||
+ return rc;
|
||||
+ if ( cr0 & CR0_EM )
|
||||
+ {
|
||||
+ generate_exception_if(type == X86EMUL_FPU_fpu, EXC_NM, -1);
|
||||
+ generate_exception_if(type == X86EMUL_FPU_mmx, EXC_UD, -1);
|
||||
+ generate_exception_if(type == X86EMUL_FPU_xmm, EXC_UD, -1);
|
||||
+ }
|
||||
+ generate_exception_if((cr0 & CR0_TS) &&
|
||||
+ (type != X86EMUL_FPU_wait || (cr0 & CR0_MP)),
|
||||
+ EXC_NM, -1);
|
||||
+ }
|
||||
+
|
||||
+ done:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
#define get_fpu(_type, _fic) \
|
||||
-do{ (_fic)->exn_raised = 0; \
|
||||
- fail_if(ops->get_fpu == NULL); \
|
||||
- rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \
|
||||
+do { \
|
||||
+ rc = _get_fpu(_type, _fic, ctxt, ops); \
|
||||
if ( rc ) goto done; \
|
||||
} while (0)
|
||||
#define _put_fpu() \
|
||||
@@ -2879,8 +2918,14 @@ x86_emulate(
|
||||
}
|
||||
|
||||
case 0x9b: /* wait/fwait */
|
||||
- emulate_fpu_insn("fwait");
|
||||
+ {
|
||||
+ struct fpu_insn_ctxt fic = { .insn_bytes = 1 };
|
||||
+
|
||||
+ get_fpu(X86EMUL_FPU_wait, &fic);
|
||||
+ asm volatile ( "fwait" ::: "memory" );
|
||||
+ put_fpu(&fic);
|
||||
break;
|
||||
+ }
|
||||
|
||||
case 0x9c: /* pushf */
|
||||
src.val = _regs.eflags;
|
||||
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
|
||||
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
|
||||
@@ -115,6 +115,7 @@ struct __packed segment_register {
|
||||
/* FPU sub-types which may be requested via ->get_fpu(). */
|
||||
enum x86_emulate_fpu_type {
|
||||
X86EMUL_FPU_fpu, /* Standard FPU coprocessor instruction set */
|
||||
+ X86EMUL_FPU_wait, /* WAIT/FWAIT instruction */
|
||||
X86EMUL_FPU_mmx, /* MMX instruction set (%mm0-%mm7) */
|
||||
X86EMUL_FPU_xmm, /* SSE instruction set (%xmm0-%xmm7/15) */
|
||||
X86EMUL_FPU_ymm /* AVX/XOP instruction set (%ymm0-%ymm7/15) */
|
Loading…
Reference in a new issue