From e18aa5057febfc3f9f61c8755234e361528def0e Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Tue, 14 Oct 2025 13:20:39 +0200 Subject: executor: introduce __addrspace_guest Apply __addrspace_guest to every guest function and use a C++ template to statically validate that host functions are not passed to executor_fn_guest_addr(). This only works in Clang builds of syz-executor, because GCC does not support address spaces, and C reproducers cannot use templates. The static check allows us to drop the dynamic checks in DEFINE_GUEST_FN_TO_GPA_FN(). While at it, replace DEFINE_GUEST_FN_TO_GPA_FN() with explicit declarations of host_fn_guest_addr() and guest_fn_guest_addr(). --- executor/common_kvm_amd64_syzos.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'executor/common_kvm_amd64_syzos.h') diff --git a/executor/common_kvm_amd64_syzos.h b/executor/common_kvm_amd64_syzos.h index 0ccc4879e..e815e087d 100644 --- a/executor/common_kvm_amd64_syzos.h +++ b/executor/common_kvm_amd64_syzos.h @@ -65,19 +65,19 @@ struct api_call_3 { #ifdef __cplusplus extern "C" { #endif -static void guest_uexit(uint64 exit_code); +GUEST_CODE static void guest_uexit(uint64 exit_code); #ifdef __cplusplus } #endif -static void guest_execute_code(uint8* insns, uint64 size); -static void guest_handle_cpuid(uint32 eax, uint32 ecx); -static void guest_handle_wrmsr(uint64 reg, uint64 val); -static void guest_handle_rdmsr(uint64 reg); -static void guest_handle_wr_crn(struct api_call_2* cmd); -static void guest_handle_wr_drn(struct api_call_2* cmd); -static void guest_handle_in_dx(struct api_call_2* cmd); -static void guest_handle_out_dx(struct api_call_3* cmd); -static void guest_handle_set_irq_handler(struct api_call_2* cmd); +GUEST_CODE static void guest_execute_code(uint8* insns, uint64 size); +GUEST_CODE static void guest_handle_cpuid(uint32 eax, uint32 ecx); +GUEST_CODE static void guest_handle_wrmsr(uint64 reg, uint64 val); +GUEST_CODE static void guest_handle_rdmsr(uint64 reg); +GUEST_CODE static void guest_handle_wr_crn(struct api_call_2* cmd); +GUEST_CODE static void guest_handle_wr_drn(struct api_call_2* cmd); +GUEST_CODE static void guest_handle_in_dx(struct api_call_2* cmd); +GUEST_CODE static void guest_handle_out_dx(struct api_call_3* cmd); +GUEST_CODE static void guest_handle_set_irq_handler(struct api_call_2* cmd); typedef enum { UEXIT_END = (uint64)-1, @@ -383,15 +383,14 @@ GUEST_CODE static void set_idt_gate(uint8 vector, uint64 handler) idt_entry->reserved = 0; } -DEFINE_GUEST_FN_TO_GPA_FN(syzos_fn_address, X86_SYZOS_ADDR_EXECUTOR_CODE, guest_uexit(UEXIT_ASSERT)) GUEST_CODE static noinline void guest_handle_set_irq_handler(struct api_call_2* cmd) { uint8 vector = (uint8)cmd->args[0]; uint64 type = cmd->args[1]; volatile uint64 handler_addr = 0; if (type == 1) - handler_addr = syzos_fn_address((uintptr_t)dummy_null_handler); + handler_addr = executor_fn_guest_addr(dummy_null_handler); else if (type == 2) - handler_addr = syzos_fn_address((uintptr_t)uexit_irq_handler); + handler_addr = executor_fn_guest_addr(uexit_irq_handler); set_idt_gate(vector, handler_addr); } -- cgit mrf-deployment