// https://syzkaller.appspot.com/bug?id=2eda2566924aa604083f1509b2a0efd205319f92 #include #include #include #include #include #include #include #include #include /* Define KVM Xen constants in case they are missing from older headers */ #ifndef KVM_XEN_VCPU_ATTR_TYPE_TIMER #define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7 #endif #ifndef KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL #define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((uint32_t)(-1)) #endif /* Local definition of the attribute struct to ensure compilation */ struct my_kvm_xen_vcpu_attr { uint16_t type; uint16_t pad[3]; union { uint64_t gpa; uint64_t hva; uint64_t pad[8]; struct { uint64_t state; uint64_t state_entry_time; uint64_t time_running; uint64_t time_runnable; uint64_t time_blocked; uint64_t time_offline; } runstate; uint32_t vcpu_id; struct { uint32_t port; uint32_t priority; uint64_t expires_ns; } timer; uint8_t vector; } u; }; #define MY_KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct my_kvm_xen_vcpu_attr) int main(void) { int kvm_fd, vm_fd, vcpu_fd; struct my_kvm_xen_vcpu_attr attr = {0}; int res; kvm_fd = open("/dev/kvm", O_RDWR); if (kvm_fd < 0) { printf("[-] Failed to open /dev/kvm: %s\n", strerror(errno)); exit(1); } printf("[+] open /dev/kvm successful.\n"); vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0); if (vm_fd < 0) { printf("[-] Failed to KVM_CREATE_VM: %s\n", strerror(errno)); exit(1); } printf("[+] KVM_CREATE_VM successful.\n"); vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0); if (vcpu_fd < 0) { printf("[-] Failed to KVM_CREATE_VCPU: %s\n", strerror(errno)); exit(1); } printf("[+] KVM_CREATE_VCPU successful.\n"); /* * Arm the Xen timer. * The guest kvmclock starts at 0 when the VM is created. * Setting expires_ns to 1 second ensures delta > 0, forcing * the hrtimer to be armed asynchronously. */ attr.type = KVM_XEN_VCPU_ATTR_TYPE_TIMER; attr.u.timer.port = 1; attr.u.timer.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL; attr.u.timer.expires_ns = 1000000000ULL; /* 1 second */ res = ioctl(vcpu_fd, MY_KVM_XEN_VCPU_SET_ATTR, &attr); if (res < 0) { printf("[-] Failed to KVM_XEN_VCPU_SET_ATTR: %s\n", strerror(errno)); exit(1); } printf("[+] KVM_XEN_VCPU_SET_ATTR successful.\n"); /* Wait for the hrtimer to fire in hardirq context */ printf("[*] Sleeping to allow timer to fire...\n"); sleep(2); printf("[+] Sleep finished.\n"); res = close(vcpu_fd); if (res < 0) { printf("[-] Failed to close vcpu_fd: %s\n", strerror(errno)); exit(1); } printf("[+] close vcpu_fd successful.\n"); res = close(vm_fd); if (res < 0) { printf("[-] Failed to close vm_fd: %s\n", strerror(errno)); exit(1); } printf("[+] close vm_fd successful.\n"); res = close(kvm_fd); if (res < 0) { printf("[-] Failed to close kvm_fd: %s\n", strerror(errno)); exit(1); } printf("[+] close kvm_fd successful.\n"); return 0; }