Skip to content

Commit 2def950

Browse files
huthbonzini
authored andcommitted
KVM: arm64: Limit length in kvm_vm_ioctl_mte_copy_tags() to INT_MAX
In case of success, this function returns the amount of handled bytes. However, this does not work for large values: The function is called from kvm_arch_vm_ioctl() (which still returns a long), which in turn is called from kvm_vm_ioctl() in virt/kvm/kvm_main.c. And that function stores the return value in an "int r" variable. So the upper 32-bits of the "long" return value are lost there. KVM ioctl functions should only return "int" values, so let's limit the amount of bytes that can be requested here to INT_MAX to avoid the problem with the truncated return value. We can then also change the return type of the function to "int" to make it clearer that it is not possible to return a "long" here. Fixes: f0376ed ("KVM: arm64: Add ioctl to fetch/store tags in a guest") Signed-off-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Gavin Shan <gshan@redhat.com> Reviewed-by: Steven Price <steven.price@arm.com> Message-Id: <20230208140105.655814-5-thuth@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent c5edd75 commit 2def950

3 files changed

Lines changed: 10 additions & 5 deletions

File tree

Documentation/virt/kvm/api.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5645,7 +5645,8 @@ with the KVM_XEN_VCPU_GET_ATTR ioctl.
56455645
};
56465646

56475647
Copies Memory Tagging Extension (MTE) tags to/from guest tag memory. The
5648-
``guest_ipa`` and ``length`` fields must be ``PAGE_SIZE`` aligned. The ``addr``
5648+
``guest_ipa`` and ``length`` fields must be ``PAGE_SIZE`` aligned.
5649+
``length`` must not be bigger than 2^31 - PAGE_SIZE bytes. The ``addr``
56495650
field must point to a buffer which the tags will be copied to or from.
56505651

56515652
``flags`` specifies the direction of copy, either ``KVM_ARM_TAGS_TO_GUEST`` or

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,8 +1005,8 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
10051005
int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
10061006
struct kvm_device_attr *attr);
10071007

1008-
long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
1009-
struct kvm_arm_copy_mte_tags *copy_tags);
1008+
int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
1009+
struct kvm_arm_copy_mte_tags *copy_tags);
10101010

10111011
/* Guest/host FPSIMD coordination helpers */
10121012
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);

arch/arm64/kvm/guest.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,8 +1019,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
10191019
return ret;
10201020
}
10211021

1022-
long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
1023-
struct kvm_arm_copy_mte_tags *copy_tags)
1022+
int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
1023+
struct kvm_arm_copy_mte_tags *copy_tags)
10241024
{
10251025
gpa_t guest_ipa = copy_tags->guest_ipa;
10261026
size_t length = copy_tags->length;
@@ -1041,6 +1041,10 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
10411041
if (length & ~PAGE_MASK || guest_ipa & ~PAGE_MASK)
10421042
return -EINVAL;
10431043

1044+
/* Lengths above INT_MAX cannot be represented in the return value */
1045+
if (length > INT_MAX)
1046+
return -EINVAL;
1047+
10441048
gfn = gpa_to_gfn(guest_ipa);
10451049

10461050
mutex_lock(&kvm->slots_lock);

0 commit comments

Comments
 (0)