All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Leonardo Bras <leonardo@linux.ibm.com>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Paul Mackerras" <paulus@ozlabs.org>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	kvm-ppc@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm
Date: Thu, 28 Nov 2019 01:00:01 +0000	[thread overview]
Message-ID: <20191128010001.GJ22227@linux.intel.com> (raw)
In-Reply-To: <41fe3962ce1f1d5f61db5f5c28584f68ad66b2b1.camel@linux.ibm.com>

On Wed, Nov 27, 2019 at 06:57:10PM -0300, Leonardo Bras wrote:
> On Wed, 2019-11-27 at 17:15 -0300, Leonardo Bras wrote:
> > > > > > So, suppose these threads, where:
> > > > > > - T1 uses a borrowed reference, and 
> > > > > > - T2 is releasing the reference (close, release):
> > > > > 
> > > > > Nit: T2 is releasing the *last* reference (as implied by your reference
> > > > > to close/release).
> > > > 
> > > > Correct.
> > > > 
> > > > > > T1                              | T2
> > > > > > kvm_get_kvm()                   |
> > > > > > ...                             | kvm_put_kvm()
> > > > > > kvm_put_kvm_no_destroy()        |
> > > > > > 
> > > > > > The above would not trigger a use-after-free bug, but will cause a
> > > > > > memory leak. Is my above understanding right?
> > > > > 
> > > > > Yes, this is correct.
> > > > > 
> > > > 
> > > > Then, what would not be a bug before (using kvm_put_kvm()) now is a
> > > > memory leak (using kvm_put_kvm_no_destroy()).
> > > 
> 
> Sorry, I missed some information on above example. 
> Suppose on that example that the reorder changes take place so that
> kvm_put_kvm{,_no_destroy}() always happens after the last usage of kvm
> (in the same syscall, let's say).

That can't happen, because the ioctl() holds a reference to KVM via its
file descriptor for /dev/kvm, and ioctl() in turn prevents the fd from
being closed.

> Before T1 and T2, refcount = 1;

This is what's impossible.  T1 must have an existing reference to get
into the ioctl(), and that reference cannot be dropped until the ioctl()
completes (and by completes I mean returns to userspace). Assuming no
other bugs, i.e. T2 has its own reference, then refcount >= 2.

> If T1 uses kvm_put_kvm_no_destroy():
> - T1 increases refcount (=2)
> - T2 decreases refcount (=1)
> - T1 decreases refcount, (=0) don't free kvm (memleak)
> 
> If T1 uses kvm_put_kvm():
> - T1 increases refcount (= 2)
> - T2 decreases refcount (= 1)
> - T1 decreases refcount, (= 0) frees kvm.
> 
> So using kvm_put_kvm_no_destroy() would introduce a memleak where it
> would have no bug.
> 
> > > No, using kvm_put_kvm_no_destroy() changes how a bug would manifest, as
> > > you note below.  Replacing kvm_put_kvm() with kvm_put_kvm_no_destroy()
> > > when the refcount is _guaranteed_ to be >1 has no impact on correctness.
> 
> Yes, you are correct. 
> But on the above case, kvm_put_kvm{,_no_destroy}() would be called
> with refcount = 1, and if reorder patch is applied, it would not cause
> any use-after-free error, even on kvm_put_kvm() case.
> 
> Is the above correct?

No, see above.

WARNING: multiple messages have this Message-ID (diff)
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Leonardo Bras <leonardo@linux.ibm.com>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Paul Mackerras" <paulus@ozlabs.org>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	kvm-ppc@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm
Date: Wed, 27 Nov 2019 17:00:01 -0800	[thread overview]
Message-ID: <20191128010001.GJ22227@linux.intel.com> (raw)
In-Reply-To: <41fe3962ce1f1d5f61db5f5c28584f68ad66b2b1.camel@linux.ibm.com>

On Wed, Nov 27, 2019 at 06:57:10PM -0300, Leonardo Bras wrote:
> On Wed, 2019-11-27 at 17:15 -0300, Leonardo Bras wrote:
> > > > > > So, suppose these threads, where:
> > > > > > - T1 uses a borrowed reference, and 
> > > > > > - T2 is releasing the reference (close, release):
> > > > > 
> > > > > Nit: T2 is releasing the *last* reference (as implied by your reference
> > > > > to close/release).
> > > > 
> > > > Correct.
> > > > 
> > > > > > T1                              | T2
> > > > > > kvm_get_kvm()                   |
> > > > > > ...                             | kvm_put_kvm()
> > > > > > kvm_put_kvm_no_destroy()        |
> > > > > > 
> > > > > > The above would not trigger a use-after-free bug, but will cause a
> > > > > > memory leak. Is my above understanding right?
> > > > > 
> > > > > Yes, this is correct.
> > > > > 
> > > > 
> > > > Then, what would not be a bug before (using kvm_put_kvm()) now is a
> > > > memory leak (using kvm_put_kvm_no_destroy()).
> > > 
> 
> Sorry, I missed some information on above example. 
> Suppose on that example that the reorder changes take place so that
> kvm_put_kvm{,_no_destroy}() always happens after the last usage of kvm
> (in the same syscall, let's say).

That can't happen, because the ioctl() holds a reference to KVM via its
file descriptor for /dev/kvm, and ioctl() in turn prevents the fd from
being closed.

> Before T1 and T2, refcount = 1;

This is what's impossible.  T1 must have an existing reference to get
into the ioctl(), and that reference cannot be dropped until the ioctl()
completes (and by completes I mean returns to userspace). Assuming no
other bugs, i.e. T2 has its own reference, then refcount >= 2.

> If T1 uses kvm_put_kvm_no_destroy():
> - T1 increases refcount (=2)
> - T2 decreases refcount (=1)
> - T1 decreases refcount, (=0) don't free kvm (memleak)
> 
> If T1 uses kvm_put_kvm():
> - T1 increases refcount (= 2)
> - T2 decreases refcount (= 1)
> - T1 decreases refcount, (= 0) frees kvm.
> 
> So using kvm_put_kvm_no_destroy() would introduce a memleak where it
> would have no bug.
> 
> > > No, using kvm_put_kvm_no_destroy() changes how a bug would manifest, as
> > > you note below.  Replacing kvm_put_kvm() with kvm_put_kvm_no_destroy()
> > > when the refcount is _guaranteed_ to be >1 has no impact on correctness.
> 
> Yes, you are correct. 
> But on the above case, kvm_put_kvm{,_no_destroy}() would be called
> with refcount == 1, and if reorder patch is applied, it would not cause
> any use-after-free error, even on kvm_put_kvm() case.
> 
> Is the above correct?

No, see above.

  reply	other threads:[~2019-11-28  1:00 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-21 22:58 [PATCH] KVM: Add separate helper for putting borrowed reference to kvm Sean Christopherson
2019-10-21 22:58 ` Sean Christopherson
2019-10-22 13:49 ` Paolo Bonzini
2019-10-22 13:49   ` Paolo Bonzini
2019-11-26 16:44 ` Leonardo Bras
2019-11-26 16:44   ` Leonardo Bras
2019-11-26 17:14   ` Sean Christopherson
2019-11-26 17:14     ` Sean Christopherson
2019-11-26 17:53     ` Leonardo Bras
2019-11-26 17:53       ` Leonardo Bras
2019-11-27 16:38       ` Paolo Bonzini
2019-11-27 16:38         ` Paolo Bonzini
2019-11-27 18:24         ` Leonardo Bras
2019-11-27 18:24           ` Leonardo Bras
2019-11-27 18:32           ` Paolo Bonzini
2019-11-27 18:32             ` Paolo Bonzini
2019-11-27 19:25             ` Leonardo Bras
2019-11-27 19:25               ` Leonardo Bras
2019-11-27 19:47               ` Sean Christopherson
2019-11-27 19:47                 ` Sean Christopherson
2019-11-27 20:15                 ` Leonardo Bras
2019-11-27 20:15                   ` Leonardo Bras
2019-11-27 21:57                   ` Leonardo Bras
2019-11-27 21:57                     ` Leonardo Bras
2019-11-28  1:00                     ` Sean Christopherson [this message]
2019-11-28  1:00                       ` Sean Christopherson
2019-11-28 16:29                       ` Leonardo Bras
2019-11-28 16:29                         ` Leonardo Bras
2019-11-28 13:49                     ` Paolo Bonzini
2019-11-28 13:49                       ` Paolo Bonzini
2019-11-28 16:04                       ` Leonardo Bras
2019-11-28 16:04                         ` Leonardo Bras
2019-11-26 17:57     ` Leonardo Bras
2019-11-26 17:57       ` 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=20191128010001.GJ22227@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=kvm-ppc@vger.kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=leonardo@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --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 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.