aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2024-09-24 15:23:14 +0200
committerAlexander Potapenko <glider@google.com>2024-09-25 09:05:57 +0000
commit4b1eded1f91812d576538f106b57352d25a6b484 (patch)
tree24d63abea11136d185dc9eba0a0ab5eb93f20046 /pkg
parent7c9588a40bd882410049d1e772de2452934a7eaf (diff)
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.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/subsystem/linux/rules.go2
-rw-r--r--pkg/subsystem/lists/linux.go2
-rw-r--r--pkg/vminfo/linux_syscalls.go22
-rw-r--r--pkg/vminfo/linux_test.go2
4 files changed, 24 insertions, 4 deletions
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.