diff options
| author | Alexey Kardashevskiy <aik@linux.ibm.com> | 2021-09-13 16:09:14 +1000 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-09-16 21:37:48 +0200 |
| commit | cac54be7ff77e2e220d7b477c82984b26157e09b (patch) | |
| tree | 60fc03f952977b5f01016916527268e4a7290bee | |
| parent | 3611c0a0c1166f09038ed05f21dbbec8f2e29834 (diff) | |
executor/common_kvm_ppc64: fuzz more hypercalls
At the moment syzkaller only fuzzes the platform architecture defined
hypercalls. However there are custom defined hypercalls which KVM handles,
they make 2 groups - an extension of hypercalls and so-called ultracalls
which are handled by the secure VM firmware but in absense of the secure
VM facility, KVM gets to handle those as errors.
This enables the two extra groups of hypercalls in KVM. If not enabled,
KVM exits to let the userspace handle them (which syzkaller does not do).
Signed-off-by: Alexey Kardashevskiy <aik@linux.ibm.com>
| -rw-r--r-- | executor/common_kvm_ppc64.h | 16 | ||||
| -rw-r--r-- | pkg/csource/generated.go | 16 | ||||
| -rw-r--r-- | pkg/ifuzz/powerpc/pseudo.go | 13 |
3 files changed, 28 insertions, 17 deletions
diff --git a/executor/common_kvm_ppc64.h b/executor/common_kvm_ppc64.h index 26ccc118d..1063e587b 100644 --- a/executor/common_kvm_ppc64.h +++ b/executor/common_kvm_ppc64.h @@ -391,14 +391,14 @@ static volatile long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volat // Hypercalls need to be enable so we enable them all here to // allow fuzzing #define MAX_HCALL 0x450 - for (unsigned hcall = 4; hcall < MAX_HCALL; hcall += 4) { - struct kvm_enable_cap cap = { - .cap = KVM_CAP_PPC_ENABLE_HCALL, - .flags = 0, - .args = {hcall, 1}, - }; - ioctl(vmfd, KVM_ENABLE_CAP, &cap); - } + for (unsigned hcall = 4; hcall < MAX_HCALL; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); + + for (unsigned hcall = 0xf000; hcall < 0xf810; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); + + for (unsigned hcall = 0xef00; hcall < 0xef20; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); // Only a few of many RTAS calls are actually in the KVM and the rest // are handled in QEMU, enable the KVM handling for those 4 here. diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index 5733a9f06..0465913fb 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -7595,14 +7595,14 @@ static volatile long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volat if (kvmppc_set_one_reg(cpufd, KVM_REG_PPC_PID, &pid)) return -1; #define MAX_HCALL 0x450 - for (unsigned hcall = 4; hcall < MAX_HCALL; hcall += 4) { - struct kvm_enable_cap cap = { - .cap = KVM_CAP_PPC_ENABLE_HCALL, - .flags = 0, - .args = {hcall, 1}, - }; - ioctl(vmfd, KVM_ENABLE_CAP, &cap); - } + for (unsigned hcall = 4; hcall < MAX_HCALL; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); + + for (unsigned hcall = 0xf000; hcall < 0xf810; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); + + for (unsigned hcall = 0xef00; hcall < 0xef20; hcall += 4) + kvm_vm_enable_cap(vmfd, KVM_CAP_PPC_ENABLE_HCALL, hcall, 1); kvmppc_define_rtas_kernel_token(vmfd, 1, "ibm,set-xive"); kvmppc_define_rtas_kernel_token(vmfd, 2, "ibm,get-xive"); kvmppc_define_rtas_kernel_token(vmfd, 3, "ibm,int-on"); diff --git a/pkg/ifuzz/powerpc/pseudo.go b/pkg/ifuzz/powerpc/pseudo.go index c2a1b568f..4790cea9f 100644 --- a/pkg/ifuzz/powerpc/pseudo.go +++ b/pkg/ifuzz/powerpc/pseudo.go @@ -81,7 +81,18 @@ func (gen *generator) sc(lev uint) { imap := gen.imap n := gen.r.Intn(9) - gen.byte(imap.ld64(3, uint64(gen.r.Intn(4+(MaxHcall-4)/4)))) + hcrange := gen.r.Intn(3) + offset := 4 + maxhc := MaxHcall + if hcrange == 1 { + offset = 0xf000 + maxhc = 0xf810 + } else if hcrange == 2 { + offset = 0xef00 + maxhc = 0xef20 + } + hc := gen.r.Intn((maxhc-offset)/4)*4 + offset + gen.byte(imap.ld64(3, uint64(hc))) for i := 4; i < n+4; i++ { gen.byte(imap.ld64(uint(i), gen.r.Uint64())) } |
