All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: return length in KVM_GET_CPUID2.
@ 2019-10-24  5:29 Matt Delco
  2019-10-24  8:24 ` [PATCH v2] " Matt Delco
  0 siblings, 1 reply; 2+ messages in thread
From: Matt Delco @ 2019-10-24  5:29 UTC (permalink / raw)
  To: kvm; +Cc: Matt Delco

KVM_GET_CPUID2 never indicates the array length it populates. If an app
passes in an array that's too short then kvm_vcpu_ioctl_get_cpuid2() populates
the required array length and returns -E2BIG.  However, its caller then just
bails to "goto out", thus bypassing the copy_to_user(). If an app
passes in an array that's not too short, then
kvm_vcpu_ioctl_get_cpuid2() doesn't populate the array length. Its
caller will then call copy_to_user(), which is pointless since no data
values have been changed.

This change attempts to have KVM_GET_CPUID2 populate the array length on
both success and failure, and still indicate -E2BIG when a provided
array is too short.  I'm not sure if this type of change is considered
an API breakage and thus we need a KVM_GET_CPUID3.

Fixes: 0771671749b59 ("KVM: Enhance guest cpuid management", 2007-11-21)
Signed-off-by: Matt Delco <delco@chromium.org>
---
 arch/x86/kvm/cpuid.c | 1 +
 arch/x86/kvm/x86.c   | 7 ++++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index f68c0c753c38..ec013b68b266 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -274,6 +274,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
 	if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
 			 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out;
+	cpuid->nent = vcpu->arch.cpuid_nent;
 	return 0;
 
 out:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5863c38108d9..4998d3bafbfd 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4161,11 +4161,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 			goto out;
 		r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
 					      cpuid_arg->entries);
-		if (r)
+		if (r && r != -E2BIG)
 			goto out;
-		r = -EFAULT;
-		if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid)))
+		if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid))) {
+			r = -EFAULT;
 			goto out;
+		}
 		r = 0;
 		break;
 	}
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH v2] KVM: x86: return length in KVM_GET_CPUID2.
  2019-10-24  5:29 [PATCH] KVM: x86: return length in KVM_GET_CPUID2 Matt Delco
@ 2019-10-24  8:24 ` Matt Delco
  0 siblings, 0 replies; 2+ messages in thread
From: Matt Delco @ 2019-10-24  8:24 UTC (permalink / raw)
  To: kvm; +Cc: Matt Delco

KVM_GET_CPUID2 never indicates the array length it populates. If an app
passes in an array that's too short then kvm_vcpu_ioctl_get_cpuid2() populates
the required array length and returns -E2BIG.  However, its caller then just
bails to "goto out", thus bypassing the copy_to_user(). If an app
passes in an array that's not too short, then
kvm_vcpu_ioctl_get_cpuid2() doesn't populate the array length. Its
caller will then call copy_to_user(), which is pointless since no data
values have been changed.

This change attempts to have KVM_GET_CPUID2 populate the array length on
both success and failure, and still indicate -E2BIG when a provided
array is too short.  I'm not sure if this type of change is considered
an API breakage and thus we need a KVM_GET_CPUID3.

Fixes: 0771671749b59 ("KVM: Enhance guest cpuid management", 2007-11-21)
Signed-off-by: Matt Delco <delco@chromium.org>
---
 arch/x86/kvm/cpuid.c | 1 +
 arch/x86/kvm/x86.c   | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index f68c0c753c38..ec013b68b266 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -274,6 +274,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
 	if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
 			 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out;
+	cpuid->nent = vcpu->arch.cpuid_nent;
 	return 0;
 
 out:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5863c38108d9..701bf4f4f6f8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4161,12 +4161,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 			goto out;
 		r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
 					      cpuid_arg->entries);
-		if (r)
+		if (r && r != -E2BIG)
 			goto out;
-		r = -EFAULT;
-		if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid)))
+		if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid))) {
+			r = -EFAULT;
 			goto out;
-		r = 0;
+		}
 		break;
 	}
 	case KVM_GET_MSRS: {
-- 
2.23.0.866.gb869b98d4c-goog


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-10-24  8:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-24  5:29 [PATCH] KVM: x86: return length in KVM_GET_CPUID2 Matt Delco
2019-10-24  8:24 ` [PATCH v2] " Matt Delco

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.