| From 3a33d030daaa7c507e1c12d5adcf828248429593 Mon Sep 17 00:00:00 2001 |
| From: Tom Roeder <tmroeder@google.com> |
| Date: Thu, 24 Jan 2019 13:48:20 -0800 |
| Subject: kvm: x86/vmx: Use kzalloc for cached_vmcs12 |
| |
| From: Tom Roeder <tmroeder@google.com> |
| |
| commit 3a33d030daaa7c507e1c12d5adcf828248429593 upstream. |
| |
| This changes the allocation of cached_vmcs12 to use kzalloc instead of |
| kmalloc. This removes the information leak found by Syzkaller (see |
| Reported-by) in this case and prevents similar leaks from happening |
| based on cached_vmcs12. |
| |
| It also changes vmx_get_nested_state to copy out the full 4k VMCS12_SIZE |
| in copy_to_user rather than only the size of the struct. |
| |
| Tested: rebuilt against head, booted, and ran the syszkaller repro |
| https://syzkaller.appspot.com/text?tag=ReproC&x=174efca3400000 without |
| observing any problems. |
| |
| Reported-by: syzbot+ded1696f6b50b615b630@syzkaller.appspotmail.com |
| Fixes: 8fcc4b5923af5de58b80b53a069453b135693304 |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Tom Roeder <tmroeder@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/vmx.c | 12 ++++++++---- |
| 1 file changed, 8 insertions(+), 4 deletions(-) |
| |
| --- a/arch/x86/kvm/vmx.c |
| +++ b/arch/x86/kvm/vmx.c |
| @@ -8315,11 +8315,11 @@ static int enter_vmx_operation(struct kv |
| if (r < 0) |
| goto out_vmcs02; |
| |
| - vmx->nested.cached_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); |
| + vmx->nested.cached_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL); |
| if (!vmx->nested.cached_vmcs12) |
| goto out_cached_vmcs12; |
| |
| - vmx->nested.cached_shadow_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); |
| + vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL); |
| if (!vmx->nested.cached_shadow_vmcs12) |
| goto out_cached_shadow_vmcs12; |
| |
| @@ -14853,13 +14853,17 @@ static int vmx_get_nested_state(struct k |
| copy_shadow_to_vmcs12(vmx); |
| } |
| |
| - if (copy_to_user(user_kvm_nested_state->data, vmcs12, sizeof(*vmcs12))) |
| + /* |
| + * Copy over the full allocated size of vmcs12 rather than just the size |
| + * of the struct. |
| + */ |
| + if (copy_to_user(user_kvm_nested_state->data, vmcs12, VMCS12_SIZE)) |
| return -EFAULT; |
| |
| if (nested_cpu_has_shadow_vmcs(vmcs12) && |
| vmcs12->vmcs_link_pointer != -1ull) { |
| if (copy_to_user(user_kvm_nested_state->data + VMCS12_SIZE, |
| - get_shadow_vmcs12(vcpu), sizeof(*vmcs12))) |
| + get_shadow_vmcs12(vcpu), VMCS12_SIZE)) |
| return -EFAULT; |
| } |
| |