aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-01-08 17:20:32 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-01-09 20:28:10 +0100
commitbbd4840872f70e3342308c6965ab196ed2606af1 (patch)
tree519ebfa1fbd6cafadd2efd1038e0c8f869ff37eb /sys
parentc377a6514d9a4858e818e6d4637870bab2da6370 (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.md1
-rw-r--r--sys/decl.go15
-rw-r--r--sys/kvm.txt95
-rw-r--r--sys/kvm_amd64.const12
-rw-r--r--sys/kvm_arm64.const12
-rw-r--r--sys/kvm_ppc64le.const12
-rw-r--r--sys/test.txt7
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])