From 08c902a39f5f7aa0e1d5fe664b2b8db458d4fb73 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 18 May 2015 12:11:31 +0200 Subject: [PATCH] x86emul: also put_fpu() on error paths fail_if() and generate_exception_if() could theoretically bypass the normal flow reaching put_fpu(), and not invoking it would leave the fpu_exception_callback pointer in place, allowing for the callback to be called at an unexpected time. Luckily the two generate_exception_if()-s that would actually trigger this are currently commented out, so this is not (yet) a (security) issue. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- xen/arch/x86/x86_emulate/x86_emulate.c | 12 +++++++++--- xen/arch/x86/x86_emulate/x86_emulate.h | 6 +++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 6c6c58a8ea..d43ca4e38e 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -670,10 +670,14 @@ do{ (_fic)->exn_raised = 0; \ rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \ if ( rc ) goto done; \ } while (0) -#define put_fpu(_fic) \ -do{ \ +#define _put_fpu() \ +do { \ if ( ops->put_fpu != NULL ) \ - ops->put_fpu(ctxt); \ + (ops->put_fpu)(ctxt); \ +} while (0) +#define put_fpu(_fic) \ +do { \ + _put_fpu(); \ generate_exception_if((_fic)->exn_raised, EXC_MF, -1); \ } while (0) @@ -3787,6 +3791,7 @@ x86_emulate( *ctxt->regs = _regs; done: + _put_fpu(); return rc; twobyte_insn: @@ -4632,5 +4637,6 @@ x86_emulate( goto writeback; cannot_emulate: + _put_fpu(); return X86EMUL_UNHANDLEABLE; } diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index 593b31e846..c55063d840 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -384,7 +384,11 @@ struct x86_emulate_ops enum x86_emulate_fpu_type type, struct x86_emulate_ctxt *ctxt); - /* put_fpu: Relinquish the FPU. Unhook from FPU/SIMD exception handlers. */ + /* + * put_fpu: Relinquish the FPU. Unhook from FPU/SIMD exception handlers. + * The handler, if installed, must be prepared to get called without + * the get_fpu one having got called before! + */ void (*put_fpu)( struct x86_emulate_ctxt *ctxt); -- 2.39.5