Commit 4b451a57 authored by Mathias Krause's avatar Mathias Krause Committed by Sean Christopherson
Browse files

KVM: selftests: Test max vCPU IDs corner cases



The KVM_CREATE_VCPU ioctl ABI had an implicit integer truncation bug,
allowing 2^32 aliases for a vCPU ID by setting the upper 32 bits of a 64
bit ioctl() argument.

It also allowed excluding a once set boot CPU ID.

Verify this no longer works and gets rejected with an error.

Signed-off-by: default avatarMathias Krause <minipli@grsecurity.net>
Link: https://lore.kernel.org/r/20240614202859.3597745-5-minipli@grsecurity.net


[sean: tweak assert message+comment for 63:32!=0 testcase]
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent d29bf2ca
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -26,10 +26,19 @@ int main(int argc, char *argv[])
	TEST_ASSERT(ret < 0,
		    "Setting KVM_CAP_MAX_VCPU_ID beyond KVM cap should fail");

	/* Test BOOT_CPU_ID interaction (MAX_VCPU_ID cannot be lower) */
	if (kvm_has_cap(KVM_CAP_SET_BOOT_CPU_ID)) {
		vm_ioctl(vm, KVM_SET_BOOT_CPU_ID, (void *)MAX_VCPU_ID);

		/* Try setting KVM_CAP_MAX_VCPU_ID below BOOT_CPU_ID */
		ret = __vm_enable_cap(vm, KVM_CAP_MAX_VCPU_ID, MAX_VCPU_ID - 1);
		TEST_ASSERT(ret < 0,
			    "Setting KVM_CAP_MAX_VCPU_ID below BOOT_CPU_ID should fail");
	}

	/* Set KVM_CAP_MAX_VCPU_ID */
	vm_enable_cap(vm, KVM_CAP_MAX_VCPU_ID, MAX_VCPU_ID);


	/* Try to set KVM_CAP_MAX_VCPU_ID again */
	ret = __vm_enable_cap(vm, KVM_CAP_MAX_VCPU_ID, MAX_VCPU_ID + 1);
	TEST_ASSERT(ret < 0,
@@ -39,6 +48,15 @@ int main(int argc, char *argv[])
	ret = __vm_ioctl(vm, KVM_CREATE_VCPU, (void *)MAX_VCPU_ID);
	TEST_ASSERT(ret < 0, "Creating vCPU with ID > MAX_VCPU_ID should fail");

	/* Create vCPU with bits 63:32 != 0, but an otherwise valid id */
	ret = __vm_ioctl(vm, KVM_CREATE_VCPU, (void *)(1L << 32));
	TEST_ASSERT(ret < 0, "Creating vCPU with ID[63:32] != 0 should fail");

	/* Create vCPU with id within bounds */
	ret = __vm_ioctl(vm, KVM_CREATE_VCPU, (void *)0);
	TEST_ASSERT(ret >= 0, "Creating vCPU with ID 0 should succeed");

	close(ret);
	kvm_vm_free(vm);
	return 0;
}