diff mbox series

[kvm-unit-tests,v2,07/16] x86/run_in_user: Preserve exception handler

Message ID 20230413184219.36404-8-minipli@grsecurity.net (mailing list archive)
State New, archived
Headers show
Series x86: cleanups, fixes and new tests | expand

Commit Message

Mathias Krause April 13, 2023, 6:42 p.m. UTC
run_in_user() replaces the exception handler for the expected fault
vector to ensure the code can properly return back to kernel mode in
case of such exceptions. However, it leaves the exception handler in
place which may confuse later test code triggering the same exception
without installing a handler first.

Fix this be restoring the previous exception handler. Running the
longjmp() handler out of context will lead to no good.

We now also need to make 'rax' volatile to avoid a related compiler
warning.

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
---
 lib/x86/usermode.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c
index b976123ca753..10fcea288a62 100644
--- a/lib/x86/usermode.c
+++ b/lib/x86/usermode.c
@@ -36,15 +36,17 @@  uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
 		uint64_t arg4, bool *raised_vector)
 {
 	extern char ret_to_kernel[];
-	uint64_t rax = 0;
+	volatile uint64_t rax = 0;
 	static unsigned char user_stack[USERMODE_STACK_SIZE];
+	handler old_ex;
 
 	*raised_vector = 0;
 	set_idt_entry(RET_TO_KERNEL_IRQ, ret_to_kernel, 3);
-	handle_exception(fault_vector,
-			restore_exec_to_jmpbuf_exception_handler);
+	old_ex = handle_exception(fault_vector,
+				  restore_exec_to_jmpbuf_exception_handler);
 
 	if (setjmp(jmpbuf) != 0) {
+		handle_exception(fault_vector, old_ex);
 		*raised_vector = 1;
 		return 0;
 	}
@@ -114,5 +116,7 @@  uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
 			:
 			"rsi", "rdi", "rcx", "rdx");
 
+	handle_exception(fault_vector, old_ex);
+
 	return rax;
 }