From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Leonardo Bras <leonardo@linux.ibm.com>
Cc: kvm-ppc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
"Paul Mackerras" <paulus@ozlabs.org>,
"Benjamin Herrenschmidt" <benh@kernel.crashing.org>,
"Michael Ellerman" <mpe@ellerman.id.au>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Radim Krčmář" <rkrcmar@redhat.com>
Subject: Re: [PATCH 1/1] powerpc/kvm/book3s: Fixes possible 'use after release' of kvm
Date: Tue, 26 Nov 2019 10:14:06 -0800 [thread overview]
Message-ID: <20191126181406.GC22233@linux.intel.com> (raw)
In-Reply-To: <20191126175212.377171-1-leonardo@linux.ibm.com>
On Tue, Nov 26, 2019 at 02:52:12PM -0300, Leonardo Bras wrote:
> Fixes a possible 'use after free' of kvm variable.
> It does use mutex_unlock(&kvm->lock) after possible freeing a variable
> with kvm_put_kvm(kvm).
Moving the calls to kvm_put_kvm() to the end of the functions doesn't
actually fix a use-after-free. In these flows, the reference being
released is a borrowed reference that KVM takes on behalf of the entity it
is creating, e.g. device, vcpu, or spapr tce. The caller of these create
helpers must also hold its own reference to @kvm on top of the borrowed
reference, i.e. these kvm_put_kvm() calls will never free @kvm (assuming
there are no refcounting bugs elsewhere in KVM).
If one these kvm_put_kvm() calls did unexpectedly free @kvm (due to a bug
somewhere else), KVM would still hit a use-after-free scenario as the
caller still thinks @kvm is valid. Currently, this would only happen on a
subsequent ioctl() on the caller's file descriptor (which holds a pointer
to @kvm), as the callers of these functions don't directly dereference
@kvm after the functions return. But, not deferencing @kvm isn't deliberate
or functionally required, it's just how the code happens to be written.
The intent of adding kvm_put_kvm_no_destroy() was primarily to document
that under no circumstance should the to-be-put reference be the *last*
reference to @kvm. Moving the call to kvm_put_kvm{_no_destroy}() doesn't
change that
> Signed-off-by: Leonardo Bras <leonardo@linux.ibm.com>
> ---
> arch/powerpc/kvm/book3s_64_vio.c | 3 +--
> virt/kvm/kvm_main.c | 8 ++++----
> 2 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index 5834db0a54c6..a402ead833b6 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -316,14 +316,13 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>
> if (ret >= 0)
> list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables);
> - else
> - kvm_put_kvm(kvm);
>
> mutex_unlock(&kvm->lock);
>
> if (ret >= 0)
> return ret;
>
> + kvm_put_kvm(kvm);
> kfree(stt);
> fail_acct:
> account_locked_vm(current->mm, kvmppc_stt_pages(npages), false);
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 13efc291b1c7..f37089b60d09 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -2744,10 +2744,8 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
> /* Now it's all set up, let userspace reach it */
> kvm_get_kvm(kvm);
> r = create_vcpu_fd(vcpu);
> - if (r < 0) {
> - kvm_put_kvm(kvm);
> + if (r < 0)
> goto unlock_vcpu_destroy;
> - }
>
> kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu;
>
> @@ -2771,6 +2769,8 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
> mutex_lock(&kvm->lock);
> kvm->created_vcpus--;
> mutex_unlock(&kvm->lock);
> + if (r < 0)
> + kvm_put_kvm(kvm);
> return r;
> }
>
> @@ -3183,10 +3183,10 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
> kvm_get_kvm(kvm);
> ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
> if (ret < 0) {
> - kvm_put_kvm(kvm);
> mutex_lock(&kvm->lock);
> list_del(&dev->vm_node);
> mutex_unlock(&kvm->lock);
> + kvm_put_kvm(kvm);
> ops->destroy(dev);
> return ret;
> }
> --
> 2.23.0
>
next prev parent reply other threads:[~2019-11-26 18:14 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-26 17:52 [PATCH 1/1] powerpc/kvm/book3s: Fixes possible 'use after release' of kvm Leonardo Bras
2019-11-26 18:14 ` Sean Christopherson [this message]
2019-11-27 16:40 ` Paolo Bonzini
2019-11-27 20:18 ` Leonardo Bras
2019-11-28 17:15 ` Leonardo Bras
2019-11-27 22:57 ` Paul Mackerras
2019-11-28 16:24 ` Leonardo Bras
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191126181406.GC22233@linux.intel.com \
--to=sean.j.christopherson@intel.com \
--cc=benh@kernel.crashing.org \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=leonardo@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=paulus@ozlabs.org \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox