kvm: Fix warning in__kvm_gpc_refresh
Subsystems (4)
PATCH 1/1 kvm: Fix warning in__kvm_gpc_refresh
Check for invalid hva address stored in data before calling kvm_gpc_activate_hva() instead of only compare with 0.
---
Syzbot reports a warning message in __kvm_gpc_refresh(). This warning requires at least one of gpa and uhva to be valid.
WARNING: CPU: 0 PID: 5090 at arch/x86/kvm/../../../virt/kvm/pfncache.c:259 __kvm_gpc_refresh+0xf17/0x1090 arch/x86/kvm/../../../virt/kvm/pfncache.c:259
We are calling it from kvm_gpc_activate_hva(). This function always calls __kvm_gpc_activate() with INVALID_GPA. Thus, uhva must be valid to disable this warning.
This patch checks for invalid hva address as well instead of only comparing hva with 0 before calling kvm_gpc_activate_hva()
syzbot has tested the proposed patch and the reproducer did not trigger any issue.
Tested on:
commit: 55027e68 Merge tag 'input-for-v6.10-rc5' of git://git... git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=16ea803a980000 kernel config: https://syzkaller.appspot.com/x/.config?x=e40800950091403a dashboard link: https://syzkaller.appspot.com/bug?extid=fd555292a1da3180fc82 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=16eeb53e980000
Note: testing is done by a robot and is best-effort only.
--- arch/x86/kvm/xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/xen.c +1 -1
@@ -881,7 +881,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) r =kvm_gpc_activate (&vcpu->arch.xen.vcpu_info_cache, data->u.gpa,sizeof (struct vcpu_info )); }else { -if (data->u.hva ==0 ) { +if (data->u.hva ==0 ||kvm_is_error_hva (data->u.hva)) {kvm_gpc_deactivate (&vcpu->arch.xen.vcpu_info_cache); r =0 ;break ;
---
base-commit: 2bfcfd584ff5ccc8bb7acde19b42570414bf880b
change-id: 20240625-bug5-5d332b5e5161
Best regards,
Signature · 1 line
Pei Li <[email protected]>
Sean Christopherson
maintainerQuoted 42 lines · Pei Li
Check for invalid hva address stored in data before calling
kvm_gpc_activate_hva()instead of only compare with 0.---
Syzbot reports a warning message in__kvm_gpc_refresh(). This warning requires at least one of gpa and uhva to be valid.WARNING: CPU: 0 PID: 5090 at arch/x86/kvm/../../../virt/kvm/pfncache.c:259 __kvm_gpc_refresh+0xf17/0x1090 arch/x86/kvm/../../../virt/kvm/pfncache.c:259We are calling it from
kvm_gpc_activate_hva(). This function always calls__kvm_gpc_activate()withINVALID_GPA. Thus, uhva must be valid to disable this warning.This patch checks for invalid hva address as well instead of only comparing hva with 0 before calling
kvm_gpc_activate_hva()syzbot has tested the proposed patch and the reproducer did not trigger any issue.
Tested on:
commit: 55027e68 Merge tag 'input-for-v6.10-rc5' of git://git... git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=16ea803a980000 kernel config: https://syzkaller.appspot.com/x/.config?x=e40800950091403a dashboard link: https://syzkaller.appspot.com/bug?extid=fd555292a1da3180fc82 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=16eeb53e980000Note: testing is done by a robot and is best-effort only.
--- arch/x86/kvm/xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/kvm/xen.c +0
-0
arch/x86/kvm/xen.c int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · line 887
Quoted 8 lines
arch/x86/kvm/xen.c +1
-1@@ -881,7 +881,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) r =kvm_gpc_activate (&vcpu->arch.xen.vcpu_info_cache, data->u.gpa,sizeof (struct vcpu_info )); }else { -if (data->u.hva ==0 ) { +if (data->u.hva ==0 ||kvm_is_error_hva (data->u.hva)) {kvm_gpc_deactivate (&vcpu->arch.xen.vcpu_info_cache); r =0 ;break ;
Hmm, I think what we want is to return -EINVAL in this case, not deactivate the
region. I could have sworn KVM does that. Gah, I caughtKVM_XEN_ATTR_TYPE_SHARED_INFO_HVA during review, but missed this one. So to fix this immediate bug, and avoid similar issues in the future, this?
arch/x86/kvm/xen.c +1 -1
@@ -741,7 +741,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) }else {void __user * hva =u64_to_user_ptr (data->u.shared_info.hva); -if (!PAGE_ALIGNED (hva) || !access_ok (hva,PAGE_SIZE )) { +if (!PAGE_ALIGNED (hva)) { r = -EINVAL ; }else if (!hva) {kvm_gpc_deactivate (&kvm->arch.xen.shinfo_cache);
virt/kvm/pfncache.c +3 -0
@@ -438,6 +438,9 @@ int kvm_gpc_activate(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len)int kvm_gpc_activate_hva (struct gfn_to_pfn_cache *gpc,unsigned long uhva,unsigned long len) { +if (!access_ok ((void __user *)uhva, len)) +return -EINVAL ; +return __kvm_gpc_activate (gpc,INVALID_GPA , uhva, len); }
Quoted 75 lines · Sean Christopherson
Quoted 42 lines · Pei Li
Check for invalid hva address stored in data before calling
kvm_gpc_activate_hva()instead of only compare with 0.---
Syzbot reports a warning message in__kvm_gpc_refresh(). This warning requires at least one of gpa and uhva to be valid.WARNING: CPU: 0 PID: 5090 at arch/x86/kvm/../../../virt/kvm/pfncache.c:259 __kvm_gpc_refresh+0xf17/0x1090 arch/x86/kvm/../../../virt/kvm/pfncache.c:259We are calling it from
kvm_gpc_activate_hva(). This function always calls__kvm_gpc_activate()withINVALID_GPA. Thus, uhva must be valid to disable this warning.This patch checks for invalid hva address as well instead of only comparing hva with 0 before calling
kvm_gpc_activate_hva()syzbot has tested the proposed patch and the reproducer did not trigger any issue.
Tested on:
commit: 55027e68 Merge tag 'input-for-v6.10-rc5' of git://git... git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=16ea803a980000 kernel config: https://syzkaller.appspot.com/x/.config?x=e40800950091403a dashboard link: https://syzkaller.appspot.com/bug?extid=fd555292a1da3180fc82 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 patch: https://syzkaller.appspot.com/x/patch.diff?x=16eeb53e980000Note: testing is done by a robot and is best-effort only.
--- arch/x86/kvm/xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/kvm/xen.c +0
-0arch/x86/kvm/xen.c int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · line 887
Quoted 8 lines
arch/x86/kvm/xen.c +1
-1@@ -881,7 +881,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) r =kvm_gpc_activate (&vcpu->arch.xen.vcpu_info_cache, data->u.gpa,sizeof (struct vcpu_info )); }else { -if (data->u.hva ==0 ) { +if (data->u.hva ==0 ||kvm_is_error_hva (data->u.hva)) {kvm_gpc_deactivate (&vcpu->arch.xen.vcpu_info_cache); r =0 ;break ;Hmm, I think what we want is to return
-EINVALin this case, not deactivate the
region. I could have sworn KVM does that. Gah, I caughtKVM_XEN_ATTR_TYPE_SHARED_INFO_HVAduring review, but missed this one. So to fix this immediate bug, and avoid similar issues in the future, this?arch/x86/kvm/xen.c +1
-1@@ -741,7 +741,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) }else {void __user * hva =u64_to_user_ptr (data->u.shared_info.hva); -if (!PAGE_ALIGNED (hva) || !access_ok (hva,PAGE_SIZE )) { +if (!PAGE_ALIGNED (hva)) { r = -EINVAL ; }else if (!hva) {kvm_gpc_deactivate (&kvm->arch.xen.shinfo_cache);virt/kvm/pfncache.c +0
-0
virt/kvm/pfncache.c int kvm_gpc_activate(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len) · line 446
Quoted 9 lines
virt/kvm/pfncache.c +3
-0@@ -438,6 +438,9 @@ int kvm_gpc_activate(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len)int kvm_gpc_activate_hva (struct gfn_to_pfn_cache *gpc,unsigned long uhva,unsigned long len) { +if (!access_ok ((void __user *)uhva, len)) +return -EINVAL ; +return __kvm_gpc_activate (gpc,INVALID_GPA , uhva, len); }
Thanks Sean. I’ll test and work on v2 based on your suggestions.
Best regards,
Pei