diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-01-08 17:20:32 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-01-09 20:28:10 +0100 |
| commit | bbd4840872f70e3342308c6965ab196ed2606af1 (patch) | |
| tree | 519ebfa1fbd6cafadd2efd1038e0c8f869ff37eb /sys | |
| parent | c377a6514d9a4858e818e6d4637870bab2da6370 (diff) | |
sys: extend kvm support
Add new pseudo syscall syz_kvm_setup_cpu that setups VCPU into
interesting states for execution. KVM is too difficult to setup otherwise.
Lots of improvements possible, but this is a starting point.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/README.md | 1 | ||||
| -rw-r--r-- | sys/decl.go | 15 | ||||
| -rw-r--r-- | sys/kvm.txt | 95 | ||||
| -rw-r--r-- | sys/kvm_amd64.const | 12 | ||||
| -rw-r--r-- | sys/kvm_arm64.const | 12 | ||||
| -rw-r--r-- | sys/kvm_ppc64le.const | 12 | ||||
| -rw-r--r-- | sys/test.txt | 7 |
7 files changed, 134 insertions, 20 deletions
diff --git a/sys/README.md b/sys/README.md index 6e2ecb75c..e8f49b5b6 100644 --- a/sys/README.md +++ b/sys/README.md @@ -58,6 +58,7 @@ rest of the type-options are type-specific: optional number of pages (e.g. vma[7]), or a range of pages (e.g. vma[2-4]) "proc": per process int (see description below), type-options: underlying type, value range start, how many values per process + "text16", "text32", "text64": machine code of the specified bitness ``` flags/len/flags also have trailing underlying type type-option when used in structs/unions/pointers. diff --git a/sys/decl.go b/sys/decl.go index d09328c91..a8170e68d 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -104,13 +104,24 @@ const ( BufferBlobRange BufferString BufferFilename + BufferText +) + +type TextKind int + +const ( + Text_x86_real TextKind = iota + Text_x86_16 + Text_x86_32 + Text_x86_64 ) type BufferType struct { TypeCommon Kind BufferKind - RangeBegin uintptr // for BufferBlobRange kind - RangeEnd uintptr // for BufferBlobRange kind + RangeBegin uintptr // for BufferBlobRange kind + RangeEnd uintptr // for BufferBlobRange kind + Text TextKind // for BufferText SubKind string Values []string // possible values for BufferString kind } diff --git a/sys/kvm.txt b/sys/kvm.txt index 193543f88..1f8f12391 100644 --- a/sys/kvm.txt +++ b/sys/kvm.txt @@ -10,7 +10,7 @@ resource fd_kvm[fd] resource fd_kvmvm[fd] resource fd_kvmcpu[fd] -syz_open_dev$kvm(dev ptr[in, string["/dev/kvm"]], id const[0], flags flags[open_flags]) fd_kvm +openat$kvm(fd const[AT_FDCWD], file ptr[in, string["/dev/kvm"]], flags flags[open_flags], mode const[0]) fd_kvm ioctl$KVM_CREATE_VM(fd fd_kvm, cmd const[KVM_CREATE_VM], type const[0]) fd_kvmvm ioctl$KVM_GET_MSR_INDEX_LIST(fd fd_kvm, cmd const[KVM_GET_MSR_INDEX_LIST], arg ptr[in, kvm_msr_list]) @@ -131,6 +131,7 @@ kvm_mcg_status = MCG_STATUS_RIPV, MCG_STATUS_EIPV, MCG_STATUS_MCIP, MCG_STATUS_L kvm_mce_status = MCI_STATUS_VAL, MCI_STATUS_OVER, MCI_STATUS_UC, MCI_STATUS_EN, MCI_STATUS_MISCV, MCI_STATUS_ADDRV, MCI_STATUS_PCC, MCI_STATUS_S, MCI_STATUS_AR kvm_caps = KVM_CAP_HYPERV_SYNIC kvm_cpuid_flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX, KVM_CPUID_FLAG_STATEFUL_FUNC, KVM_CPUID_FLAG_STATE_READ_NEXT +kvm_dev_flags = KVM_DEV_ASSIGN_ENABLE_IOMMU, KVM_DEV_ASSIGN_PCI_2_3, KVM_DEV_ASSIGN_MASK_INTX kvm_mem_slots = 0, 1, 2, 3, 4, 5, 509, 510, 511, 10000, 65536, 65537, 65538, 65539, 65540, 66047, 66048, 66049 kvm_guest_addrs = 0, 1, 2, 4, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0xd000, 0xf000, 0x100000, 0x10000 @@ -142,6 +143,78 @@ kvm_x86_efer = 1, 256, 1024, 2048, 4096, 8192, 16384, 32768 kvm_x86_dr7 = 1, 2, 4, 8, 16, 32, 64, 128 kvm_x86_rflags = 1, 2, 4, 16, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152 +# Pseudo call that setups VCPU into a reasonable interesting state for execution. +# The interface is designed for extensibility so that addition of new options does not invalidate all existing programs. +syz_kvm_setup_cpu$x86(fd fd_kvmvm, cpufd fd_kvmcpu, usermem vma[24], text ptr[in, array[kvm_text_x86, 1]], ntext len[text], flags flags[kvm_setup_flags], opts ptr[in, array[kvm_setup_opt, 0:2]], nopt len[opts]) + +kvm_text_x86 [ + textreal kvm_text_x86_real + text16 kvm_text_x86_16 + text32 kvm_text_x86_32 + text64 kvm_text_x86_64 +] [varlen] + +kvm_text_x86_real { + typ const[8, intptr] + text ptr[in, text[x86_real]] + size len[text, intptr] +} + +kvm_text_x86_16 { + typ const[16, intptr] + text ptr[in, text[x86_16]] + size len[text, intptr] +} + +kvm_text_x86_32 { + typ const[32, intptr] + text ptr[in, text[x86_32]] + size len[text, intptr] +} + +kvm_text_x86_64 { + typ const[64, intptr] + text ptr[in, text[x86_64]] + size len[text, intptr] +} + +kvm_setup_opt [ + cr0 kvm_setup_opt_cr0 + cr4 kvm_setup_opt_cr4 + efer kvm_setup_opt_efer + flags kvm_setup_opt_flags +] [varlen] + +kvm_setup_opt_cr0 { + typ const[1, int64] + val flags[kvm_x86_cr0, int64] +} + +kvm_setup_opt_cr4 { + typ const[2, int64] + val flags[kvm_x86_cr4, int64] +} + +kvm_setup_opt_efer { + typ const[3, int64] + val flags[kvm_x86_efer, int64] +} + +kvm_setup_opt_flags { + typ const[4, int64] + val flags[kvm_x86_rflags, int64] +} + +kvm_setup_flags = KVM_SETUP_PAGING, KVM_SETUP_PAE, KVM_SETUP_PROTECTED, KVM_SETUP_CPL3, KVM_SETUP_VIRT86, KVM_SETUP_SMM, KVM_SETUP_VM + +define KVM_SETUP_PAGING (1<<0) +define KVM_SETUP_PAE (1<<1) +define KVM_SETUP_PROTECTED (1<<2) +define KVM_SETUP_CPL3 (1<<3) +define KVM_SETUP_VIRT86 (1<<4) +define KVM_SETUP_SMM (1<<5) +define KVM_SETUP_VM (1<<6) + kvm_guest_debug { ctrl flags[kvm_guest_debug_flags, int32] pad const[0, int32] @@ -316,7 +389,7 @@ kvm_assigned_pci_dev { devid int32 busnr int32 devfn int32 - flags int32 + flags flags[kvm_dev_flags, int32] segnr int32 } @@ -347,10 +420,8 @@ kvm_userspace_memory_region { slot flags[kvm_mem_slots, int32] flags flags[kvm_mem_region_flags, int32] paddr flags[kvm_guest_addrs, int64] -#TODO: this should be len of addr, but it also must be multiple of page size -# there is currently to way to make kvm_guest_memory_region multiple of page size - size const[4096, int64] - addr ptr[in, kvm_guest_memory_region] + size len[addr, int64] + addr vma[1:2] } kvm_vcpu_events { @@ -627,15 +698,3 @@ kvm_coalesced_mmio_zone { size flags[kvm_guest_addr_size, int32] pad const[0, int32] } - -# This struct contains things that make sense to copy into guest. -#TODO: add page tables. -kvm_guest_memory_region [ - blob array[int8] - gdt array[kvm_gdt_entry] -] [varlen] - -#TODO: detail this struct -kvm_gdt_entry { - val int64 -} diff --git a/sys/kvm_amd64.const b/sys/kvm_amd64.const index fc625e039..f65c14546 100644 --- a/sys/kvm_amd64.const +++ b/sys/kvm_amd64.const @@ -1,4 +1,5 @@ # AUTOGENERATED FILE +AT_FDCWD = 18446744073709551516 KVM_ASSIGN_DEV_IRQ = 1077980784 KVM_ASSIGN_PCI_DEVICE = 2151722601 KVM_ASSIGN_SET_INTX_MASK = 1077980836 @@ -19,6 +20,9 @@ KVM_CREATE_VCPU = 44609 KVM_CREATE_VM = 44545 KVM_DEASSIGN_DEV_IRQ = 1077980789 KVM_DEASSIGN_PCI_DEVICE = 1077980786 +KVM_DEV_ASSIGN_ENABLE_IOMMU = 1 +KVM_DEV_ASSIGN_MASK_INTX = 4 +KVM_DEV_ASSIGN_PCI_2_3 = 2 KVM_DEV_IRQ_GUEST_INTX = 256 KVM_DEV_IRQ_GUEST_MSI = 512 KVM_DEV_IRQ_GUEST_MSIX = 1024 @@ -103,6 +107,13 @@ KVM_S390_INTERRUPT = 1074835092 KVM_S390_UCAS_MAP = 1075359312 KVM_S390_UCAS_UNMAP = 1075359313 KVM_S390_VCPU_FAULT = 1074310738 +KVM_SETUP_CPL3 = 8 +KVM_SETUP_PAE = 2 +KVM_SETUP_PAGING = 1 +KVM_SETUP_PROTECTED = 4 +KVM_SETUP_SMM = 32 +KVM_SETUP_VIRT86 = 16 +KVM_SETUP_VM = 64 KVM_SET_BOOT_CPU_ID = 44664 KVM_SET_CLOCK = 1076932219 KVM_SET_CPUID = 1074310794 @@ -154,3 +165,4 @@ MCI_STATUS_S = 72057594037927936 MCI_STATUS_UC = 2305843009213693952 MCI_STATUS_VAL = 9223372036854775808 __NR_ioctl = 16 +__NR_openat = 257 diff --git a/sys/kvm_arm64.const b/sys/kvm_arm64.const index 42c9a9016..22c92c580 100644 --- a/sys/kvm_arm64.const +++ b/sys/kvm_arm64.const @@ -1,4 +1,5 @@ # AUTOGENERATED FILE +AT_FDCWD = 18446744073709551516 KVM_ASSIGN_DEV_IRQ = 1077980784 KVM_ASSIGN_PCI_DEVICE = 2151722601 KVM_ASSIGN_SET_INTX_MASK = 1077980836 @@ -14,6 +15,9 @@ KVM_CREATE_VCPU = 44609 KVM_CREATE_VM = 44545 KVM_DEASSIGN_DEV_IRQ = 1077980789 KVM_DEASSIGN_PCI_DEVICE = 1077980786 +KVM_DEV_ASSIGN_ENABLE_IOMMU = 1 +KVM_DEV_ASSIGN_MASK_INTX = 4 +KVM_DEV_ASSIGN_PCI_2_3 = 2 KVM_DEV_IRQ_GUEST_INTX = 256 KVM_DEV_IRQ_GUEST_MSI = 512 KVM_DEV_IRQ_GUEST_MSIX = 1024 @@ -80,6 +84,13 @@ KVM_S390_INTERRUPT = 1074835092 KVM_S390_UCAS_MAP = 1075359312 KVM_S390_UCAS_UNMAP = 1075359313 KVM_S390_VCPU_FAULT = 1074310738 +KVM_SETUP_CPL3 = 8 +KVM_SETUP_PAE = 2 +KVM_SETUP_PAGING = 1 +KVM_SETUP_PROTECTED = 4 +KVM_SETUP_SMM = 32 +KVM_SETUP_VIRT86 = 16 +KVM_SETUP_VM = 64 KVM_SET_BOOT_CPU_ID = 44664 KVM_SET_CLOCK = 1076932219 KVM_SET_DEVICE_ATTR = 1075359457 @@ -106,3 +117,4 @@ KVM_UNREGISTER_COALESCED_MMIO = 1074835048 KVM_X86_GET_MCE_CAP_SUPPORTED = 2148052637 KVM_X86_SETUP_MCE = 1074310812 __NR_ioctl = 29 +__NR_openat = 56 diff --git a/sys/kvm_ppc64le.const b/sys/kvm_ppc64le.const index 9695cdf33..c178e0baa 100644 --- a/sys/kvm_ppc64le.const +++ b/sys/kvm_ppc64le.const @@ -1,4 +1,5 @@ # AUTOGENERATED FILE +AT_FDCWD = 18446744073709551516 KVM_ASSIGN_DEV_IRQ = 2151722608 KVM_ASSIGN_PCI_DEVICE = 1077980777 KVM_ASSIGN_SET_INTX_MASK = 2151722660 @@ -14,6 +15,9 @@ KVM_CREATE_VCPU = 536915521 KVM_CREATE_VM = 536915457 KVM_DEASSIGN_DEV_IRQ = 2151722613 KVM_DEASSIGN_PCI_DEVICE = 2151722610 +KVM_DEV_ASSIGN_ENABLE_IOMMU = 1 +KVM_DEV_ASSIGN_MASK_INTX = 4 +KVM_DEV_ASSIGN_PCI_2_3 = 2 KVM_DEV_IRQ_GUEST_INTX = 256 KVM_DEV_IRQ_GUEST_MSI = 512 KVM_DEV_IRQ_GUEST_MSIX = 1024 @@ -81,6 +85,13 @@ KVM_S390_INTERRUPT = 2148576916 KVM_S390_UCAS_MAP = 2149101136 KVM_S390_UCAS_UNMAP = 2149101137 KVM_S390_VCPU_FAULT = 2148052562 +KVM_SETUP_CPL3 = 8 +KVM_SETUP_PAE = 2 +KVM_SETUP_PAGING = 1 +KVM_SETUP_PROTECTED = 4 +KVM_SETUP_SMM = 32 +KVM_SETUP_VIRT86 = 16 +KVM_SETUP_VM = 64 KVM_SET_BOOT_CPU_ID = 536915576 KVM_SET_CLOCK = 2150674043 KVM_SET_DEVICE_ATTR = 2149101281 @@ -107,3 +118,4 @@ KVM_UNREGISTER_COALESCED_MMIO = 2148576872 KVM_X86_GET_MCE_CAP_SUPPORTED = 1074310813 KVM_X86_SETUP_MCE = 2148052636 __NR_ioctl = 54 +__NR_openat = 286 diff --git a/sys/test.txt b/sys/test.txt index b48ca8f5f..2c7eb0d0c 100644 --- a/sys/test.txt +++ b/sys/test.txt @@ -203,6 +203,13 @@ syz_end_var_struct { syz_test$vma0(v0 vma, l0 len[v0], v1 vma[5], l1 len[v1], v2 vma[7:9], l2 len[v2]) +# Text type. + +syz_test$text_x86_real(a0 ptr[in, text[x86_real]], a1 len[a0]) +syz_test$text_x86_16(a0 ptr[in, text[x86_16]], a1 len[a0]) +syz_test$text_x86_32(a0 ptr[in, text[x86_32]], a1 len[a0]) +syz_test$text_x86_64(a0 ptr[in, text[x86_64]], a1 len[a0]) + # Regression tests. syz_test$regression0(a0 ptr[inout, syz_regression0_struct]) |
