aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_arm64.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2024-07-23 11:32:12 +0200
committerAlexander Potapenko <glider@google.com>2024-07-29 15:29:47 +0000
commitd44a00853f501db00c2c9e47b8c770b892d57721 (patch)
treec23f3b508c544d0591bf876c0b5ab90498f94bbc /executor/common_kvm_arm64.h
parent3fac346ac6e2c0adadc6a268582fc50fc07f16f2 (diff)
executor: arm64: add syzos header
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.
Diffstat (limited to 'executor/common_kvm_arm64.h')
-rw-r--r--executor/common_kvm_arm64.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/executor/common_kvm_arm64.h b/executor/common_kvm_arm64.h
index b4de3cfcf..ba02e244b 100644
--- a/executor/common_kvm_arm64.h
+++ b/executor/common_kvm_arm64.h
@@ -5,6 +5,7 @@
// Implementation of syz_kvm_setup_cpu pseudo-syscall.
+#include "common_kvm_arm64_syzos.h"
#include "kvm.h"
// Register encodings from https://docs.kernel.org/virt/kvm/api.html.
@@ -108,10 +109,15 @@ static volatile long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volat
// Guest physical memory layout:
// 0x00000000 - unused pages
// 0xeeee0000 - user code (1 page)
+ // 0xeeee8000 - executor guest code (4 pages)
// 0xffff1000 - EL1 stack (1 page)
struct addr_size allocator = {.addr = host_mem, .size = guest_mem_size};
int slot = 0; // Slot numbers do not matter, they just have to be different.
+ struct addr_size host_text = alloc_guest_mem(&allocator, 4 * page_size);
+ memcpy(host_text.addr, &__start_guest, (char*)&__stop_guest - (char*)&__start_guest);
+ vm_set_user_memory_region(vmfd, slot++, KVM_MEM_READONLY, ARM64_ADDR_EXECUTOR_CODE, host_text.size, (uintptr_t)host_text.addr);
+
struct addr_size next = alloc_guest_mem(&allocator, page_size);
// Fill the guest code page with RET instructions to be on the safe side.
fill_with_ret(next.addr, next.size);
@@ -134,7 +140,8 @@ static volatile long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volat
ioctl(cpufd, KVM_ARM_VCPU_INIT, &init);
// Set up CPU registers.
- vcpu_set_reg(cpufd, KVM_ARM64_REGS_PC, ARM64_ADDR_USER_CODE);
+ // PC points to the relative offset of guest_main() within the guest code.
+ vcpu_set_reg(cpufd, KVM_ARM64_REGS_PC, ARM64_ADDR_EXECUTOR_CODE + ((uint64)guest_main - (uint64)&__start_guest));
vcpu_set_reg(cpufd, KVM_ARM64_REGS_SP_EL1, ARM64_ADDR_EL1_STACK_BOTTOM + page_size - 128);
return 0;