diff options
| author | Alexander Potapenko <glider@google.com> | 2026-02-10 17:21:32 +0100 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2026-02-11 07:33:38 +0000 |
| commit | 5f58a1979fcf122ff2115a2d83857e75fd0d6260 (patch) | |
| tree | 126ae7ef3dab8170b85f37e24dd7522b5069a224 /executor | |
| parent | c96f11a3a42272152e5af9b801a32490748f1f7e (diff) | |
executor: minor uexit changes in guest_main() for amd64
Use UEXIT_END to indicate normal guest termination, and UEXIT_INVALID_MAIN
to indicate malformed guest program.
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/common_kvm_amd64_syzos.h | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/executor/common_kvm_amd64_syzos.h b/executor/common_kvm_amd64_syzos.h index 99e881b73..9ff5af6d0 100644 --- a/executor/common_kvm_amd64_syzos.h +++ b/executor/common_kvm_amd64_syzos.h @@ -172,6 +172,7 @@ typedef enum { UEXIT_END = (uint64)-1, UEXIT_IRQ = (uint64)-2, UEXIT_ASSERT = (uint64)-3, + UEXIT_INVALID_MAIN = (uint64)-4, } uexit_code; typedef enum { @@ -183,7 +184,10 @@ __attribute__((naked)) GUEST_CODE static void dummy_null_handler() { - asm("iretq"); + asm volatile(R"( + movq $-2, %%rdi + call guest_uexit + )" ::: "memory", "rdi", "cc"); } __attribute__((naked)) GUEST_CODE static void uexit_irq_handler() @@ -223,11 +227,11 @@ guest_main(uint64 cpu) while (size >= sizeof(struct api_call_header)) { struct api_call_header* cmd = (struct api_call_header*)addr; - if (cmd->call >= SYZOS_API_STOP) - return; - if (cmd->size > size) - return; volatile uint64 call = cmd->call; + if ((call >= SYZOS_API_STOP) || (cmd->size > size)) { + guest_uexit(UEXIT_INVALID_MAIN); + return; + } if (call == SYZOS_API_UEXIT) { // Issue a user exit. struct api_call_uexit* ucmd = (struct api_call_uexit*)cmd; @@ -312,7 +316,7 @@ guest_main(uint64 cpu) addr += cmd->size; size -= cmd->size; }; - guest_uexit((uint64)-1); + guest_uexit(UEXIT_END); } GUEST_CODE static noinline void guest_execute_code(uint8* insns, uint64 size) @@ -838,24 +842,10 @@ GUEST_CODE static noinline void setup_l2_page_tables(cpu_vendor_id vendor, uint6 } else if (r.gpa == X86_SYZOS_ADDR_STACK_BOTTOM) { // Map stack to the VM's dedicated stack buffer backing = X86_SYZOS_ADDR_VM_STACK(cpu_id, vm_id); - } else if (r.gpa == X86_SYZOS_ADDR_ZERO || - r.gpa == X86_SYZOS_ADDR_VAR_IDT || - r.gpa == X86_SYZOS_ADDR_BOOT_ARGS || - r.gpa == X86_SYZOS_ADDR_PT_POOL || - r.gpa == X86_SYZOS_ADDR_VAR_TSS) { - // Critical System Regions: Allocate and COPY from L1. - // We must copy the PT POOL because the PD entries in ADDR_ZERO - // point to tables allocated here. If we don't copy, L2 sees - // empty page tables and cannot resolve addresses like 0x50000. - // GDT/IDT/TSS/BootArgs are also copied for valid environment. - backing = guest_alloc_page(); - guest_memcpy((void*)backing, (void*)gpa, KVM_PAGE_SIZE); - } else if (r.flags & MEM_REGION_FLAG_EXECUTOR_CODE) { - // Identity map the Executor Code. - backing = gpa; } else { - // Allocate new backing memory - backing = guest_alloc_page(); + // Identity map all other regions to prevent L1 OOM exhaustion. + // The L2 guest is transient and does not need duplicates of L1's GDT/IDT/TSS/Heap. + backing = gpa; } l2_map_page(cpu_id, vm_id, gpa, backing, flags); } @@ -1194,7 +1184,7 @@ GUEST_CODE static noinline void init_vmcs_host_state(void) vmwrite(VMCS_HOST_TR_SELECTOR, X86_SYZOS_SEL_TSS64); // Base addresses. - vmwrite(VMCS_HOST_TR_BASE, 0); + vmwrite(VMCS_HOST_TR_BASE, X86_SYZOS_ADDR_VAR_TSS); vmwrite(VMCS_HOST_GDTR_BASE, X86_SYZOS_ADDR_GDT); vmwrite(VMCS_HOST_IDTR_BASE, X86_SYZOS_ADDR_VAR_IDT); vmwrite(VMCS_HOST_FS_BASE, rdmsr(X86_MSR_FS_BASE)); |
