From 402f603f49d544ba363605c8527b59cec162e878 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 18 Mar 2008 16:02:36 +0000 Subject: [PATCH] x86: check ModR/M mod bits for CR/DR access insns Signed-off-by: Jan Beulich Signed-off-by: Keir Fraser --- xen/arch/x86/traps.c | 8 ++++++++ xen/arch/x86/x86_emulate.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 09217029a1..90cad36296 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1801,6 +1801,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0x20: /* MOV CR?, */ opcode = insn_fetch(u8, code_base, eip, code_limit); + if ( opcode < 0xc0 ) + goto fail; modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1841,6 +1843,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0x21: /* MOV DR?, */ opcode = insn_fetch(u8, code_base, eip, code_limit); + if ( opcode < 0xc0 ) + goto fail; modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1851,6 +1855,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0x22: /* MOV ,CR? */ opcode = insn_fetch(u8, code_base, eip, code_limit); + if ( opcode < 0xc0 ) + goto fail; modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1897,6 +1903,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0x23: /* MOV ,DR? */ opcode = insn_fetch(u8, code_base, eip, code_limit); + if ( opcode < 0xc0 ) + goto fail; modrm_reg += ((opcode >> 3) & 7) + (lock << 3); modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 224cefb52c..b3bb4deb52 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -3219,8 +3219,8 @@ x86_emulate( case 0x21: /* mov dr,reg */ case 0x22: /* mov reg,cr */ case 0x23: /* mov reg,dr */ + generate_exception_if(ea.type != OP_REG, EXC_UD, -1); generate_exception_if(!mode_ring0(), EXC_GP, 0); - modrm_rm |= (rex_prefix & 1) << 3; modrm_reg |= lock_prefix << 3; if ( b & 2 ) { -- 2.39.5