public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Michal Luczaj <mhal@rbox.co>
Subject: Re: [PATCH v2 07/16] KVM: Store gfn_to_pfn_cache length as an immutable property
Date: Tue, 22 Nov 2022 18:59:06 +0000	[thread overview]
Message-ID: <Y30b+sdz5OpcdCWj@google.com> (raw)
In-Reply-To: <ac74694957b5f3af46e0668ca58388eb90ecda9e.camel@infradead.org>

On Mon, Nov 21, 2022, David Woodhouse wrote:
> On Mon, 2022-11-21 at 19:11 +0000, Sean Christopherson wrote:
> > On Mon, Nov 21, 2022, David Woodhouse wrote:
> > > I won't fight for it, but I quite liked the idea that each user of a
> > > GPC would know how much space *it* is going to access, and provide that
> > > length as a required parameter. I do note you've added a WARN_ON to one
> > > such user, and that's great — but overall, this patch makes that
> > > checking *optional* instead of mandatory.
> > 
> > I honestly don't see a meaningful difference in this case.  The only practical
> > difference is that shoving @len into the cache makes the check a one-time thing.
> > The "mandatory" check at use time still relies on a human to not make a mistake.
> > If the check were derived from the actual access, a la get_user(), then I would
> > feel differently.
> >
> > Case in point, the mandatory check didn't prevent KVM from screwing up bounds
> > checking in kvm_xen_schedop_poll().  The PAGE_SIZE passed in for @len is in no
> > way tied to actual access that's being performed, the code is simply regurgitating
> > the size of the cache.
> 
> True, but that's a different class of bug, and the human needs to make
> a more *egregious* mistake.
> 
> If the function itself writes outside the size that *it* thinks *it's*
> going to write, right there and then in that function, that's utterly
> hosed (and the SCHEDOP_poll thing was indeed so hosed).

Yes, such mistakes are more egregious in the sense they are harder to find and
have more severe consequences, but I don't think the mistakes are necessarily
harder to make.  Bugs in simple usage patterns are easy to spot, but at the same
time they're also less likely to be buggy because they're simpler.

> The mandatory check *did* save us from configuring a 32-bit runstate
> area at the end of a page, then *writing* to it in 64-bit mode (where
> it's larger) and running off the end of the page.

Only because the length/capacity wasn't immutable, i.e. that particilar bug couldn't
have been introduced in the first place if kvm_gpc_activate() was the only "public"
API that allowed "changing" the length.

That's really what I dislike.  I have no objection to adding a sanity check, what
I think is broken and dangerous is allowing a gpc->gpa to effectively become valid
by refreshing with a smaller length.

The gfn_to_hva_cache APIs have the same problem, but they get away with it because
they don't support concurrent usage and don't have to deal with invalidation events.

Lastly, if we keep "length" then we also need to keep "gpa", otherwise the resulting
API is all kinds of funky.

E.g. I'd be totally ok with something like this that would allow users to opt-in
to sanity checking their usage.

int __kvm_gpc_lock(struct gfn_to_pfn_cache *gpc)
{
	int r;

	read_lock_irqsave(&gpc->lock, gpc->flags);

	while (kvm_gpc_check(gpc)) {
                 read_unlock_irqrestore(&gpc->lock, gpc->flags);

                 r = kvm_gpc_refresh(gpc);
		 if (r)
                         return r;

                 read_lock_irqsave(&gpc->lock, gpc->flags);
	}

	return 0;
}

int kvm_gpc_lock(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len)
{
	if (WARN_ON_ONCE(gpa < gpc->gpa || (gpa + len > PAGE_SIZE) ||
			 ((gpa & PAGE_MASK) != (gpc->gpa & PAGE_MASK)))
		return -EINVAL;	

	return __kvm_gpc_lock(gpc);
}


  reply	other threads:[~2022-11-22 18:59 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-13 21:12 [PATCH v2 00/16] KVM: x86: gfn_to_pfn_cache fixes and cleanups Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 01/16] KVM: Initialize gfn_to_pfn_cache locks in dedicated helper Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 02/16] KVM: Reject attempts to consume or refresh inactive gfn_to_pfn_cache Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 03/16] KVM: x86: Always use non-compat vcpu_runstate_info size for gfn=>pfn cache Sean Christopherson
2022-10-27 11:11   ` Paolo Bonzini
2022-10-27 14:44     ` Sean Christopherson
2022-10-27 15:03       ` Paolo Bonzini
2022-10-27 15:10         ` Sean Christopherson
2022-10-27 16:56       ` Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 04/16] KVM: Shorten gfn_to_pfn_cache function names Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 05/16] KVM: x86: Remove unused argument in gpc_unmap_khva() Sean Christopherson
2022-12-02  9:28   ` Like Xu
2022-12-02 10:57     ` Michal Luczaj
2022-12-02 14:21       ` David Woodhouse
2022-12-02 17:01         ` Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 06/16] KVM: Store immutable gfn_to_pfn_cache properties Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 07/16] KVM: Store gfn_to_pfn_cache length as an immutable property Sean Christopherson
2022-11-21 14:26   ` David Woodhouse
2022-11-21 19:11     ` Sean Christopherson
2022-11-21 20:02       ` David Woodhouse
2022-11-22 18:59         ` Sean Christopherson [this message]
2022-10-13 21:12 ` [PATCH v2 08/16] KVM: Use gfn_to_pfn_cache's immutable "kvm" in kvm_gpc_check() Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 09/16] KVM: Clean up hva_to_pfn_retry() Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 10/16] KVM: Use gfn_to_pfn_cache's immutable "kvm" in kvm_gpc_refresh() Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 11/16] KVM: Drop KVM's API to allow temprorarily unmapping gfn=>pfn cache Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 12/16] KVM: Do not partially reinitialize gfn=>pfn cache during activation Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 13/16] KVM: Drop @gpa from exported gfn=>pfn cache check() and refresh() helpers Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 14/16] KVM: Skip unnecessary "unmap" if gpc is already valid during refresh Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 15/16] KVM: selftests: Add tests in xen_shinfo_test to detect lock races Sean Christopherson
2022-10-13 21:12 ` [PATCH v2 16/16] KVM: selftests: Mark "guest_saw_irq" as volatile in xen_shinfo_test Sean Christopherson

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=Y30b+sdz5OpcdCWj@google.com \
    --to=seanjc@google.com \
    --cc=dwmw2@infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhal@rbox.co \
    --cc=pbonzini@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