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: Mon, 21 Nov 2022 19:11:35 +0000	[thread overview]
Message-ID: <Y3vNZ0Y3KUVsrFcM@google.com> (raw)
In-Reply-To: <f80338c90d90fcd2ae3c592c55a591b1d46e6678.camel@infradead.org>

On Mon, Nov 21, 2022, David Woodhouse wrote:
> On Thu, 2022-10-13 at 21:12 +0000, Sean Christopherson wrote:
> > From: Michal Luczaj <mhal@rbox.co>
> > 
> > Make the length of a gfn=>pfn cache an immutable property of the cache
> > to cleanup the APIs and avoid potential bugs, e.g calling check() with a
> > larger size than refresh() could put KVM into an infinite loop.
> 
> Hm, that's a strange hypothetical bug to be worried about, given the
> pattern is usually to have the check() and refresh() within a few lines
> of each other with just atomicity/locking stuff in between them.

Why do you say it's strange to be worried about?  The GPC and Xen code is all quite
complex and has had multiple bugs, several of which are not exactly edge cases.
I don't think it's at all strange to want to make it difficult to introduce a bug
that would in many ways be worse than panicking the kernel.

But as Paolo said, the APIs themselves are to blame[*], check() and refresh()
shouldn't be split for the common case, i.e. this particular concern should largely
be a non-issue in the long run.

[*] https://lore.kernel.org/all/c61f6089-57b7-e00f-d5ed-68e62237eab0@redhat.com

> 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.

> > All current (and anticipated future) users access the cache with a
> > predetermined size, which isn't a coincidence as using a dedicated cache
> > really only make sense when the access pattern is "fixed".
> 
> In fixing up the runstate area, I've made that not true. Not only does
> the runstate area change size at runtime if the guest changes between
> 32-bit and 64-bit mode, but it also now uses *two* GPCs to cope with a
> region that crosses a page boundary, and the size of the first
> therefore changes according to how much fits on the tail of the page.
> 
> > Add a WARN in kvm_setup_guest_pvclock() to assert that the offset+size
> > matches the length of the cache, both to make it more obvious that the
> > length really is immutable in that case, and to detect future bugs.
> ...
> > @@ -3031,13 +3030,13 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
> >  	struct pvclock_vcpu_time_info *guest_hv_clock;
> >  	unsigned long flags;
> >  
> > +	WARN_ON_ONCE(gpc->len != offset + sizeof(*guest_hv_clock));
> > +
> 
> That ought to be 'gpc->len < offset + sizeof(*guest_hv_clock)' I think?
> 
> In the case where we are writing a clock *within* a mapped Xen
> vcpu_info structure, it doesn't have to be at the *end* of that
> structure. I think the xen_shinfo_test should have caught that?

The WARN doesn't get false positive because "struct pvclock_vcpu_time_info" is
placed at the end of "struct vcpu_info" and "struct compat_vcpu_info".
 
I don't have a strong opinion on whether it's "!=" of "<", my goal in adding the
WARN was primarily to show that @len really is immutable in this case.  Guarding
against future overrun bugs was a bonus.

  reply	other threads:[~2022-11-21 19:12 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 [this message]
2022-11-21 20:02       ` David Woodhouse
2022-11-22 18:59         ` Sean Christopherson
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=Y3vNZ0Y3KUVsrFcM@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