From 4b1eded1f91812d576538f106b57352d25a6b484 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Tue, 24 Sep 2024 15:23:14 +0200 Subject: executor: arm64: sys/linux: implement syz_kvm_setup_syzos_vm and 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. --- pkg/subsystem/linux/rules.go | 2 +- pkg/subsystem/lists/linux.go | 2 +- pkg/vminfo/linux_syscalls.go | 22 ++++++++++++++++++++-- pkg/vminfo/linux_test.go | 2 ++ 4 files changed, 24 insertions(+), 4 deletions(-) (limited to 'pkg') diff --git a/pkg/subsystem/linux/rules.go b/pkg/subsystem/linux/rules.go index f152c2695..78adee1e9 100644 --- a/pkg/subsystem/linux/rules.go +++ b/pkg/subsystem/linux/rules.go @@ -49,7 +49,7 @@ var ( "isofs": {"syz_mount_image$iso9660"}, "jffs2": {"syz_mount_image$jffs2"}, "jfs": {"syz_mount_image$jfs"}, - "kvm": {"syz_kvm_setup_cpu", "syz_kvm_vgic_v3_setup"}, + "kvm": {"syz_kvm_setup_cpu", "syz_kvm_vgic_v3_setup", "syz_kvm_setup_syzos_vm", "syz_kvm_add_vcpu"}, "minix": {"syz_mount_image$minix"}, "nilfs": {"syz_mount_image$nilfs2"}, "ntfs3": {"syz_mount_image$ntfs", "syz_mount_image$ntfs3"}, diff --git a/pkg/subsystem/lists/linux.go b/pkg/subsystem/lists/linux.go index 73eecdba9..67e209019 100644 --- a/pkg/subsystem/lists/linux.go +++ b/pkg/subsystem/lists/linux.go @@ -2372,7 +2372,7 @@ func subsystems_linux() []*Subsystem { kvm = Subsystem{ Name: "kvm", - Syscalls: []string{"syz_kvm_setup_cpu", "syz_kvm_vgic_v3_setup"}, + Syscalls: []string{"syz_kvm_setup_cpu", "syz_kvm_vgic_v3_setup", "syz_kvm_setup_syzos_vm", "syz_kvm_add_vcpu"}, Lists: []string{"kvm@vger.kernel.org"}, Parents: []*Subsystem{&kernel}, PathRules: []PathRule{ diff --git a/pkg/vminfo/linux_syscalls.go b/pkg/vminfo/linux_syscalls.go index 0effafa33..2a4694906 100644 --- a/pkg/vminfo/linux_syscalls.go +++ b/pkg/vminfo/linux_syscalls.go @@ -81,6 +81,8 @@ var linuxSyscallChecks = map[string]func(*checkContext, *prog.Syscall) string{ "syz_usb_ep_read": linuxCheckUSBEmulation, "syz_kvm_setup_cpu": linuxSyzKvmSetupCPUSupported, "syz_kvm_vgic_v3_setup": linuxSyzKvmVgicV3SetupSupported, + "syz_kvm_setup_syzos_vm": linuxSyzKvmSetupSyzosVMSupported, + "syz_kvm_add_vcpu": linuxSyzKvmAddVcpuSupported, "syz_emit_vhci": linuxVhciInjectionSupported, "syz_init_net_socket": linuxSyzInitNetSocketSupported, "syz_genetlink_get_family_id": linuxSyzGenetlinkGetFamilyIDSupported, @@ -168,6 +170,8 @@ func linuxCheckUSBEmulation(ctx *checkContext, call *prog.Syscall) string { return ctx.rootCanOpen("/dev/raw-gadget") } +const unsupportedArch = "unsupported arch" + func linuxSyzKvmSetupCPUSupported(ctx *checkContext, call *prog.Syscall) string { switch call.Name { case "syz_kvm_setup_cpu$x86": @@ -183,14 +187,28 @@ func linuxSyzKvmSetupCPUSupported(ctx *checkContext, call *prog.Syscall) string return "" } } - return "unsupported arch" + return unsupportedArch } func linuxSyzKvmVgicV3SetupSupported(ctx *checkContext, call *prog.Syscall) string { if ctx.target.Arch == targets.ARM64 { return "" } - return "unsupported arch" + return unsupportedArch +} + +func linuxSyzKvmSetupSyzosVMSupported(ctx *checkContext, call *prog.Syscall) string { + if ctx.target.Arch == targets.ARM64 { + return "" + } + return unsupportedArch +} + +func linuxSyzKvmAddVcpuSupported(ctx *checkContext, call *prog.Syscall) string { + if ctx.target.Arch == targets.ARM64 { + return "" + } + return unsupportedArch } func linuxSupportedMount(ctx *checkContext, call *prog.Syscall) string { diff --git a/pkg/vminfo/linux_test.go b/pkg/vminfo/linux_test.go index 5295f4e94..4df5b017a 100644 --- a/pkg/vminfo/linux_test.go +++ b/pkg/vminfo/linux_test.go @@ -46,8 +46,10 @@ func TestLinuxSyscalls(t *testing.T) { t.Fatal(err) } expectDisabled := map[string]bool{ + "syz_kvm_add_vcpu": true, "syz_kvm_setup_cpu$arm64": true, "syz_kvm_setup_cpu$ppc64": true, + "syz_kvm_setup_syzos_vm": true, "syz_kvm_vgic_v3_setup": true, } // All mount and syz_mount_image calls except for ext4 and binder will be disabled. -- cgit mrf-deployment