aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_amd64_syzos.h
Commit message (Collapse)AuthorAgeFilesLines
* executor: move common SYZOS API call descriptors to common_kvm_syzos.h6eanut2026-02-261-25/+0
|
* executor: restore dummy_null_handler()Alexander Potapenko2026-02-171-7/+2
| | | | | Somehow one of the previous patches made dummy_null_handler() behave like uexit_irq_handler(). Restore the original handler behavior.
* executor: minor uexit changes in guest_main() for amd64Alexander Potapenko2026-02-111-24/+14
| | | | | Use UEXIT_END to indicate normal guest termination, and UEXIT_INVALID_MAIN to indicate malformed guest program.
* executor: rework L1 segment setup in SYZOSAlexander Potapenko2026-02-091-3/+4
| | | | | | | | | | | | | | This commit corrects the GDT setup for the data and TSS segments in L1. Previously, the data segment was incorrectly using the TSS base address, and the TSS base address was not properly set. The data segment base is now set to 0, as it should be for a flat 64-bit model. The TSS segment descriptor in the GDT now correctly points to X86_SYZOS_ADDR_VAR_TSS and uses the full 64-bit address. The attributes are also updated to mark the TSS as busy. Additionally, the TSS region is now explicitly copied from L1 to L2 to ensure the L2 environment has a valid TSS.
* executor: sys/linux: Implement nested SYZOS loadingAlexander Potapenko2026-02-091-96/+444
| | | | | | | | | | | | | | | | | | | This commit introduces the `SYZOS_API_NESTED_LOAD_SYZOS` command to enable running full SYZOS programs within a nested L2 guest, enhancing fuzzing capabilities for nested virtualization. Key changes include: - Nested SYZOS Execution: The new command loads a SYZOS program into an L2 VM, setting up its execution environment. - ABI Refinement: Program size is now passed via the shared `syzos_globals` memory region instead of registers, standardizing the ABI for L1 and L2. - L2 State Management: Improved saving and restoring of L2 guest GPRs across VM-exits using inline assembly wrappers for Intel and AMD. - Nested UEXIT Propagation: Intercepts EPT/NPT faults on the exit page to capture the L2 exit code from saved registers and forward it to L0 with an incremented nesting level. - L2 Memory Management: Updates to L2 page table setup, including skipping NO_HOST_MEM regions to force exits, and a new `l2_gpa_to_pa` helper.
* executor: implement L2 memory mirroring and dynamic code loadingAlexander Potapenko2026-02-091-33/+103
| | | | | | | | | | | | | | | | Refactor the SYZOS L1 guest to construct L2 page tables dynamically by mirroring its own memory layout (provided via boot arguments) instead of using a static 2MB identity map. This change introduces l2_map_page to allocate unique backing memory for most regions, while mapping X86_SYZOS_ADDR_USER_CODE and X86_SYZOS_ADDR_STACK_BOTTOM to specific per-VM buffers reserved in L1. This allows L1 to inject code and stack content into backing buffers while the L2 guest executes them from standard virtual addresses. Additionally, MEM_REGION_FLAG_* definitions are moved to the guest header to support this logic.
* executor: reorder includes in SYZOS headers6eanut2026-01-311-2/+3
| | | | | | | | | Reorder include directives in SYZOS headers to follow the project's include ordering rules. https://google.github.io/styleguide/cppguide.html#Names_and_Order_of_Includes Signed-off-by: 6eanut <jiakaiPeanut@gmail.com>
* executor: implement dynamic L2 page table allocation in SYZOSAlexander Potapenko2026-01-261-11/+66
| | | | | | | | | | | | | | | | | | | Enable the SYZOS guest (L1) to dynamically allocate memory for nested L2 page tables, replacing the previous rigid static layout. Move the mem_region and syzos_boot_args struct definitions to the guest header (common_kvm_amd64_syzos.h) to allow the guest to parse the memory map injected by the host. Introduce a bump allocator, guest_alloc_page(), which targets the X86_SYZOS_ADDR_UNUSED heap. This allocator relies on a new struct syzos_globals located at X86_SYZOS_ADDR_GLOBALS to track the allocation offset. Refactor setup_l2_page_tables() to allocate intermediate paging levels (PDPT, PD, PT) via guest_alloc_page() instead of using fixed contiguous offsets relative to the PML4. This allows for disjoint memory usage and supports future recursion requirements.
* executor: sys/linux: SYZOS: add AMD VMLOAD and VMSAVE primitivesAlexander Potapenko2026-01-201-0/+32
| | | | | | | | | | | | This patch introduces SYZOS_API_NESTED_AMD_VMLOAD and SYZOS_API_NESTED_AMD_VMSAVE. These primitives allow the L1 guest to execute the VMLOAD and VMSAVE instructions, which load/store additional guest state (FS, GS, TR, LDTR, etc.) to/from the VMCB specified by the 'vm_id' argument. This stresses the KVM L0 instruction emulator, which must validate the L1-provided physical address in RAX and perform the state transfer.
* executor: sys/linux: SYZOS: add AMD SET_INTERCEPT primitiveAlexander Potapenko2026-01-191-0/+33
| | | | | | | | | | | | | | | This patch introduces SYZOS_API_NESTED_AMD_SET_INTERCEPT to SYZOS. This primitive enables the fuzzer to surgically modify intercept vectors in the AMD VMCB (Virtual Machine Control Block) Control Area. It implements a read-modify-write operation on 32-bit VMCB offsets, allowing the L1 hypervisor (SYZOS) to deterministically set or clear specific intercept bits (e.g., for RDTSC, HLT, or exceptions) for the L2 guest. This capability allows syzkaller to systematically explore KVM's nested SVM emulation logic by toggling intercepts on and off, rather than relying on static defaults or random memory corruption.
* executor: sys/linux: SYZOS: add support for AMD Nested Event InjectionAlexander Potapenko2026-01-151-0/+33
| | | | | | | | | | | | | Implement SYZOS_API_NESTED_AMD_INJECT_EVENT to allow the L1 guest to inject events (Interrupts, NMIs, Exceptions) into L2 via the VMCB EVENTINJ field. This primitive abstracts the VMCB bit-packing logic (Vector, Type, Valid, Error Code) into a high-level API, enabling the fuzzer to semantically mutate event injection parameters. This targets KVM's nested event merging logic, specifically where L0 must reconcile L1-injected events with Host-pending events.
* executor: sys/linux: SYZOS: add support for AMD STGI and CLGI instructionsAlexander Potapenko2026-01-151-0/+26
| | | | | | | | | Implement the SYZOS_API_NESTED_AMD_STGI and SYZOS_API_NESTED_AMD_CLGI primitives to toggle the Global Interrupt Flag (GIF). These commands execute the stgi and clgi instructions respectively and require no arguments. Also add a test checking that CLGI correctly masks NMI injection from L0.
* executor: sys/linux: SYZOS: add support for AMD INVLPGA instructionAlexander Potapenko2026-01-141-0/+18
| | | | | | | | | | Implement the SYZOS_API_NESTED_AMD_INVLPGA primitive to execute the INVLPGA instruction in the L1 guest. This allows the fuzzer to target KVM's Shadow MMU and Nested Paging (NPT) logic by invalidating TLB entries for specific ASIDs. Also add a simple syzlang seed/regression test.
* executor: apply optnone to guest_handle_nested_vmentry_intel()Alexander Potapenko2025-11-281-1/+4
| | | | | | | | | | | | | Florent Revest reported ThinLTO builds failing with the following error: <inline asm>:2:1: error: symbol 'after_vmentry_label' is already defined after_vmentry_label: ^ error: cannot compile inline asm , which turned out to be caused by the compiler not respecting `noinline`. Adding __attribute__((optnone)) (or optimize("O0") on GCC) fixes the issue.
* executor: sys/linux: implement SYZOS_API_NESTED_AMD_VMCB_WRITE_MASKAlexander Potapenko2025-11-211-0/+23
| | | | | | | | | | | The new command allows mutation of AMD VMCB block with plain 64-bit writes. In addition to VM ID and VMCB offset, @nested_amd_vmcb_write_mask takes three 64-bit numbers: the set mask, the unset mask, and the flip mask. This allows to make bitwise modifications to VMCB without disturbing the execution too much. Also add sys/linux/test/amd64-syz_kvm_nested_amd_vmcb_write_mask to test the new command behavior.
* executor: sys/linux: implement SYZOS_API_NESTED_INTEL_VMWRITE_MASKAlexander Potapenko2025-11-211-0/+28
| | | | | | | | | | | | The new command allows mutation of Intel VMCS fields with the help of vmwrite instruction. In addition to VM ID and field ID, @nested_intel_vmwrite_mask takes three 64-bit numbers: the set mask, the unset mask, and the flip mask. This allows to make bitwise modifications to VMCS without disturbing the execution too much. Also add sys/linux/test/amd64-syz_kvm_nested_vmwrite_mask to test the new command behavior.
* executor: sys/linux/test: handle RDTSCP in L2Alexander Potapenko2025-11-211-3/+18
| | | | | | | Enable basic RDTSCP handling. Ensure that Intel hosts exit on RDTSCP in L2, and that both Intel and AMD can handle RDTSCP exits. Add amd64-syz_kvm_nested_vmresume-rdtscp to test that.
* executor: x86: factor out common code in rdmsr()/wrmsr()Alexander Potapenko2025-11-211-37/+21
| | | | | | | | | | While at it, fix a bug in rdmsr() that apparently lost the top 32 bits. Also fix a bug in Intel's Secondary Processor-based Controls: we were incorrectly using the top 32 bits of X86_MSR_IA32_VMX_PROCBASED_CTLS2 to enable all the available controls without additional setup. This only worked because rdmsr() zeroed out those top bits.
* executor: sys/linux/test: handle RDTSC in L2Alexander Potapenko2025-11-211-3/+15
| | | | | | | Enable basic RDTSC handling. Ensure that Intel hosts exit on RDTSC in L2, and that both Intel and AMD can handle RDTSC exits. Add amd64-syz_kvm_nested_vmresume-rdtsc to test that.
* executor: sys/linux/test: basic CPUID handling in L2Alexander Potapenko2025-11-211-9/+20
| | | | | Ensure L2 correctly exits to L1 on CPUID and resumes properly. Add a test.
* executor: sys/linux: implement SYZOS_API_NESTED_VMRESUMEAlexander Potapenko2025-11-201-18/+59
| | | | | | | | | | | | | | | Provide the SYZOS API command to resume L2 execution after a VM exit, using VMRESUME on Intel and VMRUN on AMD. For testing purpose, implement basic handling of the INVD instruction: - enable INVD interception on AMD (set all bits in VMCB 00Ch); - map EXIT_REASON_INVD and VMEXIT_INVD into SYZOS_NESTED_EXIT_REASON_INVD; - advance L2 RIP to skip to the next instruction. While at it, perform minor refactorings of L2 exit reason handling. sys/linux/test/amd64-syz_kvm_nested_vmresume tests the new command by executing two instructions, INVD and HLT, in the nested VM.
* executor: x86: retire UEXIT_STOP_L2Alexander Potapenko2025-11-201-6/+3
| | | | | | | It was useful initially for vendor-agnostic tests, but given that we have guest_uexit_l2() right before it, we can save an extra L2-L1 exit. Perhaps this should increase the probability of executing more complex payloads (fewer KVM_RUN calls to reach the same point in L2 code).
* executor: sys/linux: implement SYZOS_API_NESTED_VMLAUNCHAlexander Potapenko2025-11-191-1/+200
| | | | | | | | | | | | Provide a SYZOS API command to launch the L2 VM using the VMLAUNCH (Intel) or VMRUN (AMD) instruction. For testing purposes, each L2->L1 exit is followed by a guest_uexit_l2() returning the exit code to L0. Common exit reasons (like HLT) will be mapped into a common exit code space (0xe2e20000 | reason), so that a single test can be used for both Intel and AMD. Vendor-specific exit codes will be returned using the 0xe2110000 mask for Intel and 0xe2aa0000 for AMD.
* executor: sys/linux: implement SYZOS_API_NESTED_LOAD_CODEAlexander Potapenko2025-11-191-0/+41
| | | | The new command loads an instruction blob into the specified L2 VM.
* executor: sys/linux: renumber SYZOS API IDsAlexander Potapenko2025-11-191-13/+13
| | | | | | | | Now that we are using volatiles in guest_main(), there is no particular need to base the numbers on primes (this didn't work well with Clang anyway). Instead, group the commands logically and leave some space between the groups for future updates.
* executor: x86: implement SYZOS_API_NESTED_CREATE_VMAlexander Potapenko2025-11-191-0/+412
| | | | | | Provide basic setup for registers, page tables, and segments to create Intel/AMD-based nested virtual machines. Note that the machines do not get started yet.
* executor: x86: implement SYZOS_API_ENABLE_NESTEDAlexander Potapenko2025-11-191-0/+118
| | | | | | Add vendor-specific code to turn on nested virtualization on Intel and AMD. Also provide get_cpu_vendor() to pick the correct implementation.
* executor: add include guards to KVM headersAlexander Potapenko2025-10-271-0/+5
| | | | | Not having these results in three copies of every KVM-related #define in each reproducer.
* executor: introduce __addrspace_guestAlexander Potapenko2025-10-171-13/+12
| | | | | | | | | | | | 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: amd64: remove the switch from guest_main()Alexander Potapenko2025-10-171-31/+35
| | | | Somehow Clang still manages to emit a jump table for it.
* executor: sys/linux: implement SYZOS_API_SET_IRQ_HANDLERAlexander Potapenko2025-10-171-1/+70
| | | | | | | | | | The new API call allows to initialize the handler with one of the three possible values: - NULL (should cause a page fault) - dummy_null_handler (should call iret) - uexit_irq_handler (should perform guest_uexit(UEXIT_IRQ)) Also add a test for uexit_irq_handler()
* executor: rework GDT setup for SYZOSAlexander Potapenko2025-10-171-0/+7
| | | | | Untangle SYZOS GDT setup from the legacy one. Drop LDT and TSS for now.
* executor: rename SYZOS-related address definitionsAlexander Potapenko2025-10-171-2/+2
| | | | | | | To distinguish SYZOS addresses from other x86 definitions, change them to start with X86_SYZOS_ADDR_ No functional change.
* sys/linux: executor: add IN_DX and OUT_DX to SYZOS x86 APIAlexander Potapenko2025-09-191-0/+67
| | | | | | | | Add SYZOS calls that correspond to the IN and OUT x86 instructions that perform port I/O. These instructions have different variants, for now we just implement the one that takes the port number from DX instead of encoding it in the opcode.
* sys/linux: executor: implement SYZOS_API_WR_DRN on x86Alexander Potapenko2025-09-191-0/+45
| | | | | Add a SYZOS call to write to one of the debug registers (DR0-DR7).
* executor: introduce __no_stack_protector and use it for guest codeAlexander Potapenko2025-09-111-11/+1
| | | | | | | | | | | When compiling the executor in syz-env-old, -fstack-protector may kick in and introduce global accesses that tools/check-syzos.sh reports. To prevent this, introduce the __no_stack_protector macro attribute that disable stack protection for the function in question, and use it for guest code. While at it, factor out some common definitions into common_kvm_syzos.h
* executor: x86: fix check-syzos errorAlexander Potapenko2025-09-111-14/+16
| | | | | Replace the switch statement in guest_handle_wr_crn() with a series of if statements.
* sys/linux: executor: implement SYZOS_API_WR_CRN on x86Alexander Potapenko2025-07-241-0/+37
| | | | | Add a SYZOS call to write to one of the system registers (CR0, CR2, CR3, CR4, CR8).
* executor/common_kvm_amd64_syzos.h: add _handle_ to function namesAlexander Potapenko2025-07-241-9/+9
| | | | | | Let's try to stick to the convention of naming every SYZOS API handler syzos_handle_something(). No functional change.
* executor: sys/linux/dev_kvm_amd64.txt: implement rdmsr/wrmsrAlexander Potapenko2025-07-241-0/+54
| | | | Let SYZOS execute RDMSR and WRMSR on x86.
* executor/common_kvm_amd64_syzos.h: add a missing breakAlexander Potapenko2025-07-241-0/+1
|
* executor: sys/linux: use sparse IDs for SYZOS APIAlexander Potapenko2025-07-241-3/+7
| | | | | | Like we already do on ARM, use prime numbers multiplied by 10 for SYZOS API IDs to prevent the compiler from emitting a jump table in guest_main().
* executor/kvm: add SYZOS support for CPUIDMarios Pomonis2025-05-191-0/+21
| | | | | This commit adds support for CPUID instructions on AMD64. It also adds a relevant test.
* executor/kvm: add x86-64 SYZOS fuzzerMarios Pomonis2025-04-231-0/+96
This commit adds the actual SyzOS fuzzer for x86-64 and a small test. It also updates some necessary parts of the ARM version and adds some glue for i386.