aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_arm64.h
Commit message (Collapse)AuthorAgeFilesLines
* executor: sys/linux: Add VCPU fd to `syz_kvm_assert_syzos_uexit`Alexander Potapenko2026-01-161-6/+21
| | | | | | | | Enhance the debugging capabilities of C reproducers by passing the VCPU file descriptor to the syz_kvm_assert_syzos_uexit function. With access to the VCPU fd, the function can now dump the VCPU's register state upon assertion failure, providing critical context for debugging guest execution issues.
* 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-10/+1
| | | | | | | | | | | | 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: unify ARM64_ADDR_EXECUTOR_CODE and X86_SYZOS_ADDR_EXECUTOR_CODEAlexander Potapenko2025-10-171-1/+1
| | | | | Use SYZOS_ADDR_EXECUTOR_CODE instead of both. Also put platform-specific definitions under #if GOARCH_xxx.
* executor: introduce DEFINE_GUEST_FN_TO_GPA_FN()Alexander Potapenko2025-10-171-1/+10
| | | | | DEFINE_GUEST_FN_TO_GPA_FN() allows to define helper functions to calculate guest addresses in the host/guest code.
* executor: sys/linux/: pkg/runtest: pkg/vminfo: add syz_kvm_assert_syzos_kvm_exitAlexander Potapenko2025-09-191-0/+1
| | | | Implement a pseudo-syscall to check the value of kvm_run.exit_reason
* executor/kvm: bug fix and minor refactor in KVMMarios Pomonis2025-03-271-5/+0
| | | | | | | | | | | | | | | | * Fixes a bug when setting up a 64-bit guest by making the bit manipulation macros produce unsigned long long: To create a VCPU that has paging enabled, one needs to set the CR0.PE and CR0.PG bits in CR0. The latter is problematic when setting up a 64-bit guest since if the macro is not using 1ULL, it sign extends the output (in 64-bit mode the control registers are extended to 64-bits with some of the CR0[32:63] bits reserved). This results in either failing the KVM_SET_SREGS ioctl (in newer kernel versions) or just failing the KVM_RUN ioctl with EXIT_REASON_INVALID_STATE. * Moved the bit manipulation definitions from the amd64 specific to the generic kvm header to consolidate them with the already existing ones. Prefixed them with X86_ to avoid confusion.
* executor: pkg/vminfo: sys/linux: arm64: implement syz_kvm_assert_reg()Alexander Potapenko2024-12-181-0/+19
| | | | Add a pseudo-syscall to assert on register values.
* pkg/vminfo: sys/linux: executor: define syz_kvm_assert_syzos_uexit()Alexander Potapenko2024-12-111-0/+19
| | | | | The new pseudo-syscall will serve as a test assertion, checking the uexit return value. This is going to help us validate SyzOS code.
* executor: arm: check for zero VM handle in syz_kvm_add_vcpu()Alexander Potapenko2024-12-061-1/+7
| | | | | | | | | When running syscalls asynchronously, syz_kvm_add_vcpu() sometimes receives a zero VM handle, on which it then crashes. Check for the zero value to ensure stability of the tests in sys/linux/tests. Also make sure to set errno for the pseudo-syscall in the cases where it's not done by the underlying syscalls.
* executor: arm64: detect data relocations in SyzOSAlexander Potapenko2024-12-051-1/+28
| | | | | | | Detect and report ADRP instructions in the linked binaries to avoid crashes inside SyzOS. See https://github.com/google/syzkaller/issues/5565 for more context.
* executor: arm64: sys/linux: allocate 1024 pages for guest address spaceAlexander Potapenko2024-11-261-20/+11
| | | | | | | Pass 1024 pages of memory to both syz_kvm_setup_syzos_vm() and syz_kvm_setup_cpu$arm64() to make sure that: - there is enough memory for guest allocations (e.g. ITS pages) - host can tamper with that memory, provoking more bugs
* executor: arm64: allocate memory for ITS tables on the host sideAlexander Potapenko2024-11-261-0/+6
|
* executor: arm64: use KVM_PAGE_SIZE instead of 0x1000Alexander Potapenko2024-11-261-1/+1
|
* executor: arm64: rename SYZ_KVM_* to KVM_*Alexander Potapenko2024-09-251-16/+16
| | | | | It is more common for the constants in the executor to not have the SYZ_ prefix.
* executor: arm64: store CPU ID in TPIDR_EL1Alexander Potapenko2024-09-251-0/+3
| | | | | | | | | Let SYZOS distinguish CPUs inside VM by storing their ID in TPIDR_EL1. Make sure existing code uses that ID: - in guest_handle_msr(), to ensure concurrent calls do not write to the same cache line; - in gicv3_irq_enable(), to ensure proper CPU ID is being used for IRQ setup.
* executor: arm64: sys/linux: implement syz_kvm_setup_syzos_vm and ↵Alexander Potapenko2024-09-251-52/+119
| | | | | | | | | | | | | | | | | | | | | | | syz_kvm_add_vcpu The old syz_kvm_setup_cpu() API mixed together VM and VCPU setup, making it harder to create and fuzz two VCPUs in the same VM. Introduce two new pseudo-syscalls, syz_kvm_setup_syzos_vm() and syz_kvm_add_vcpu(), that will simplify this task. syz_kvm_setup_syzos_vm() takes a VM file descriptor, performs VM setup (allocates guest memory and installs SYZOS code into it) and returns a new kvm_syz_vm resource, which is in fact a pointer to `struct kvm_syz_vm` encapsulating VM-specific data in the C code. syz_kvm_add_vcpu() takes the VM ID denoted by kvm_syz_vm and creates a new VCPU within that VM with a proper CPU number. It then stores the fuzzer-supplied SYZOS API sequence into the corresponding part (indexed by CPU number) of the VM memory slot, and sets up the CPU registers to interpret that sequence. The new pseudo-syscall let the fuzzer create independent CPUs that run different code sequences without interfering with each other.
* executor: arm64: factor out install_user_code()Alexander Potapenko2024-09-251-22/+42
| | | | | | | | Prepare to let multiple (up to 4) CPUs run different pieces of code by allocating 4 pages for ARM64_ADDR_USER_CODE. Pass the CPU id to guest_main(), so that it can pick the correct starting addres. syz_kvm_setup_cpu() will implicitly use cpuid=0 to retain its current functionality.
* executor: arm64: factor out setup_vm()Alexander Potapenko2024-09-251-34/+41
| | | | | | | | | No functional change. For multiple CPUs within the same VM, calls to syz_kvm_setup_cpu() will set up the VM memory space multiple times, so only the last one will take effect. Prepare to decouple VM setup from CPU setup by factoring this code out of syz_kvm_setup_cpu().
* executor: arm64: reserve a dedicated dirty page regionAlexander Potapenko2024-09-111-2/+9
| | | | | To ease fuzzing the dirty ring, explicitly reserve two pages with the KVM_MEM_LOG_DIRTY_PAGES flag at known address.
* executor: pkg/vminfo: sys/linux: define syz_kvm_vgic_v3_setupAlexander Potapenko2024-09-031-1/+79
| | | | | The new pseudo-syscall sets up VGICv3 IRQ controller on the host. That still requires guest setup code, which will be submitted separately.
* executor: arm64: add SYZOS_API_MSRAlexander Potapenko2024-08-051-0/+3
| | | | | | | | | | | | | MSR is an ARM64 instruction that writes a value from a GP register to one of the system CPU registers. Exposing those registers to a fuzzer will let us trigger unexpected behavior in handling them on the kernel side. The SYZOS_API_MSR call has two int64 arguments, register ID and value. Register IDs are 64-bit values obtained from ARM64_SYS_REG() in the Linux asm/kvm.h UAPI header. Same register IDs are used by ioctl$KVM_GET_ONE_REG and ioctl$KVM_SET_ONE_REG. Also add sys/linux/test/syz_kvm_setup_cpu_arm64-msr
* executor: arm64: sys/linux: introduce syzos APIAlexander Potapenko2024-07-291-9/+9
| | | | | | | | | | | | | | | | | | | | | | Allow guest payload to call syzos API functions. The available calls are enumerated by SYZOS_API_* constants, and have a form of: struct api_call { uint64 call; uint64 struct_size; /* arbitrary call-related data here */ }; Complex instruction sequences are too easy to break, so most of the time fuzzer won't be able to efficiently mutate them. We replace kvm_text_arm64 with a sequence of `struct api_call`, making it possible to intermix assembly instructions (SYZOS_API_CODE) with higher-level constructs. Right now the supported calls are: - SYZOS_API_UEXIT - abort from KVM_RUN (1 argument: exit code, uint64) - SYZOS_API_CODE - execute an ARM64 assembly blob (1 argument: inline array of int32's)
* executor: arm64: add syzos headerAlexander Potapenko2024-07-291-1/+8
| | | | | | | | | | For KVM fuzzing we are going to need some library code that will be running inside KVM to perform common tasks (e.g. register accesses, device setup etc.) This code will reside in a special ".guest" section that the executor will map at address 0xeeee8000. For now it contains just the main function, but will be extended in further patches.
* executor: arm64: more flexible physical page allocationAlexander Potapenko2024-07-291-14/+75
| | | | | | | Refactor phys page allocation in syz_kvm_setup_cpu$arm64 to prepare for more address ranges. Load user-supplied code at ARM64_ADDR_USER_CODE and allocate EL1 stack at ARM64_ADDR_EL1_STACK_BOTTOM.
* executor: arm64: call KVM_ARM_PREFERRED_TARGET on vmfd instead of cpufdAlexander Potapenko2024-04-181-1/+3
|
* sys: skip kvm const extraction for non i386/amd64Aleksandr Nogikh2021-09-131-1/+1
| | | | | | | | | | | | It is impossible to compile a number of definitions in include/uapi/linux/kvm.h for other platforms, which leads to syz-extract failing to update constants. Skip processing of this file for all arches except i386 and amd64. This is a hacky and (hopefully) temporary solution until #2754 is implemented.
* executor: warn about C89-style var declarationsDmitry Vyukov2020-08-141-3/+2
| | | | | | | | | | | | | | | | | We generally use the newer C99 var declarations combined with initialization because: - declarations are more local, reduced scope - fewer lines of code - less potential for using uninit vars and other bugs However, we have some relic code from times when we did not understand if we need to stick with C89 or not. Also some external contributions that don't follow style around. Add a static check for C89-style declarations and fix existing precedents. Akaros toolchain uses -std=gnu89 (or something) and does not allow variable declarations inside of for init statement. And we can't switch it to -std=c99 because Akaros headers are C89 themselves. So in common.h we need to declare loop counters outside of for.
* executor: remove NONFAILING from pseudo-syscallsDmitry Vyukov2020-07-151-11/+6
| | | | | | This is not needed anymore afer the previous commit. Fixes #1918
* executor: prevent non-null expected warningsDmitry Vyukov2019-03-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | The added test triggers warnings like these: <stdin>: In function ‘syz_mount_image.constprop’: <stdin>:298:3: error: argument 1 null where non-null expected [-Werror=nonnull] In file included from <stdin>:26:0: /usr/include/x86_64-linux-gnu/sys/stat.h:320:12: note: in a call to function ‘mkdir’ declared here extern int mkdir (const char *__path, __mode_t __mode) ^~~~~ cc1: all warnings being treated as errors <stdin>: In function ‘syz_open_procfs.constprop’: <stdin>:530:41: error: ‘%s’ directive argument is null [-Werror=format-truncation=] <stdin>:85:110: note: in definition of macro ‘NONFAILING’ <stdin>:532:41: error: ‘%s’ directive argument is null [-Werror=format-truncation=] <stdin>:85:110: note: in definition of macro ‘NONFAILING’ <stdin>:534:41: error: ‘%s’ directive argument is null [-Werror=format-truncation=] <stdin>:85:110: note: in definition of macro ‘NONFAILING’ Use volatile for all arguments of syz_ functions to prevent compiler from treating the arguments as constants in reproducers. Popped up during bisection that used a repro that previously worked. Update #501
* executor: introduce uint64/32/16/8 typesDmitry Vyukov2017-12-271-5/+5
| | | | | | | | | | | | | | | The "define uint64_t unsigned long long" were too good to work. With a different toolchain I am getting: cstdint:69:11: error: expected unqualified-id using ::uint64_t; ^ executor/common.h:34:18: note: expanded from macro 'uint64_t' Do it the proper way: introduce uint64/32/16/8 types and use them. pkg/csource then does s/uint64/uint64_t/ to not clutter code with additional typedefs.
* sys, executor: more kvm improvementsDmitry Vyukov2017-01-121-0/+84
1. Basic support for arm64 kvm testing. 2. Fix compiler warnings in x86 kvm code. 3. Test all pseudo syz calls in csource. 4. Fix handling of real code in x86.