From: Sean Christopherson <seanjc@google.com>
To: Like Xu <like.xu.linux@gmail.com>
Cc: Alex Williamson <alex.williamson@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v2 1/2] KVM: eventfd: Fix NULL deref irqbypass producer
Date: Wed, 16 Aug 2023 11:37:16 -0700 [thread overview]
Message-ID: <ZN0XXKezcXjv1GWH@google.com> (raw)
In-Reply-To: <20230802051700.52321-2-likexu@tencent.com>
On Wed, Aug 02, 2023, Like Xu wrote:
> From: Like Xu <likexu@tencent.com>
>
> Adding guard logic to make irq_bypass_register/unregister_producer()
> looks for the producer entry based on producer pointer itself instead
> of pure token matching.
>
> As was attempted commit 4f3dbdf47e15 ("KVM: eventfd: fix NULL deref
> irqbypass consumer"), two different producers may occasionally have two
> identical eventfd's. In this case, the later producer may unregister
> the previous one after the registration fails (since they share the same
> token), then NULL deref incurres in the path of deleting producer from
> the producers list.
>
> Registration should also fail if a registered producer changes its
> token and registers again via the same producer pointer.
>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Signed-off-by: Like Xu <likexu@tencent.com>
> Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
> ---
> virt/lib/irqbypass.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/virt/lib/irqbypass.c b/virt/lib/irqbypass.c
> index 28fda42e471b..e0aabbbf27ec 100644
> --- a/virt/lib/irqbypass.c
> +++ b/virt/lib/irqbypass.c
> @@ -98,7 +98,7 @@ int irq_bypass_register_producer(struct irq_bypass_producer *producer)
> mutex_lock(&lock);
>
> list_for_each_entry(tmp, &producers, node) {
> - if (tmp->token == producer->token) {
> + if (tmp->token == producer->token || tmp == producer) {
> ret = -EBUSY;
> goto out_err;
> }
> @@ -148,7 +148,7 @@ void irq_bypass_unregister_producer(struct irq_bypass_producer *producer)
> mutex_lock(&lock);
>
> list_for_each_entry(tmp, &producers, node) {
> - if (tmp->token != producer->token)
> + if (tmp != producer)
What are the rules for using these APIs? E.g. is doing unregister without
first doing a register actually allowed? Ditto for having multiple in-flight
calls to (un)register the exact same producer or consumer.
E.g. can we do something like the below, and then remove the list iteration to
find the passed in pointer (which is super odd IMO). Obviously not a blocker
for this patch, but it seems like we could achieve a simpler and more performant
implementation if we first sanitize the rules and the usage.
diff --git a/virt/lib/irqbypass.c b/virt/lib/irqbypass.c
index 28fda42e471b..be0ba4224a23 100644
--- a/virt/lib/irqbypass.c
+++ b/virt/lib/irqbypass.c
@@ -90,6 +90,9 @@ int irq_bypass_register_producer(struct irq_bypass_producer *producer)
if (!producer->token)
return -EINVAL;
+ if (WARN_ON_ONCE(producer->node.prev && !list_empty(&producer->node)))
+ return -EINVAL;
+
might_sleep();
if (!try_module_get(THIS_MODULE))
@@ -140,6 +143,9 @@ void irq_bypass_unregister_producer(struct irq_bypass_producer *producer)
if (!producer->token)
return;
+ if (WARN_ON_ONCE(!producer->node.prev || list_empty(&producer->node)))
+ return;
+
might_sleep();
if (!try_module_get(THIS_MODULE))
next prev parent reply other threads:[~2023-08-16 18:37 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-02 5:16 [PATCH v2 0/2] KVM: irqbypass: XArray conversion and a deref fix Like Xu
2023-08-02 5:16 ` [PATCH v2 1/2] KVM: eventfd: Fix NULL deref irqbypass producer Like Xu
2023-08-16 18:37 ` Sean Christopherson [this message]
2023-09-25 7:59 ` Like Xu
2023-08-02 5:17 ` [PATCH v2 2/2] KVM: irqbypass: Convert producers/consumers single linked list to XArray Like Xu
2023-08-02 18:30 ` Alex Williamson
2023-09-25 15:24 ` Like Xu
2023-09-26 9:18 ` Like Xu
2023-10-11 11:24 ` Like Xu
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=ZN0XXKezcXjv1GWH@google.com \
--to=seanjc@google.com \
--cc=alex.williamson@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=like.xu.linux@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--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