From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: kvm@vger.kernel.org, marc.zyngier@arm.com, andreyknvl@google.com,
linux-kernel@vger.kernel.org, pbonzini@redhat.com,
kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 1/2] kvm: Fix mmu_notifier release race
Date: Tue, 25 Apr 2017 20:49:05 +0200 [thread overview]
Message-ID: <20170425184904.GI5713@potion> (raw)
In-Reply-To: <1493028624-29837-2-git-send-email-suzuki.poulose@arm.com>
2017-04-24 11:10+0100, Suzuki K Poulose:
> The KVM uses mmu_notifier (wherever available) to keep track
> of the changes to the mm of the guest. The guest shadow page
> tables are released when the VM exits via mmu_notifier->ops.release().
> There is a rare chance that the mmu_notifier->release could be
> called more than once via two different paths, which could end
> up in use-after-free of kvm instance (such as [0]).
>
> e.g:
>
> thread A thread B
> ------- --------------
>
> get_signal-> kvm_destroy_vm()->
> do_exit-> mmu_notifier_unregister->
> exit_mm-> kvm_arch_flush_shadow_all()->
> exit_mmap-> spin_lock(&kvm->mmu_lock)
> mmu_notifier_release-> ....
> kvm_arch_flush_shadow_all()-> .....
> ... spin_lock(&kvm->mmu_lock) .....
> spin_unlock(&kvm->mmu_lock)
> kvm_arch_free_kvm()
> *** use after free of kvm ***
I don't understand this race ...
a piece of code in mmu_notifier_unregister() says:
/*
* Wait for any running method to finish, of course including
* ->release if it was run by mmu_notifier_release instead of us.
*/
synchronize_srcu(&srcu);
and code before that removes the notifier from the list, so it cannot be
called after we pass this point. mmu_notifier_release() does roughly
the same and explains it as:
/*
* synchronize_srcu here prevents mmu_notifier_release from returning to
* exit_mmap (which would proceed with freeing all pages in the mm)
* until the ->release method returns, if it was invoked by
* mmu_notifier_unregister.
*
* The mmu_notifier_mm can't go away from under us because one mm_count
* is held by exit_mmap.
*/
synchronize_srcu(&srcu);
The call of mmu_notifier->release is protected by srcu in both cases and
while it seems possible that mmu_notifier->release would be called
twice, I don't see a combination that could result in use-after-free
from mmu_notifier_release after mmu_notifier_unregister() has returned.
Doesn't [2/2] solve the exact same issue (that the release method cannot
be called twice in parallel)?
Thanks.
WARNING: multiple messages have this Message-ID (diff)
From: rkrcmar@redhat.com (Radim Krčmář)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] kvm: Fix mmu_notifier release race
Date: Tue, 25 Apr 2017 20:49:05 +0200 [thread overview]
Message-ID: <20170425184904.GI5713@potion> (raw)
In-Reply-To: <1493028624-29837-2-git-send-email-suzuki.poulose@arm.com>
2017-04-24 11:10+0100, Suzuki K Poulose:
> The KVM uses mmu_notifier (wherever available) to keep track
> of the changes to the mm of the guest. The guest shadow page
> tables are released when the VM exits via mmu_notifier->ops.release().
> There is a rare chance that the mmu_notifier->release could be
> called more than once via two different paths, which could end
> up in use-after-free of kvm instance (such as [0]).
>
> e.g:
>
> thread A thread B
> ------- --------------
>
> get_signal-> kvm_destroy_vm()->
> do_exit-> mmu_notifier_unregister->
> exit_mm-> kvm_arch_flush_shadow_all()->
> exit_mmap-> spin_lock(&kvm->mmu_lock)
> mmu_notifier_release-> ....
> kvm_arch_flush_shadow_all()-> .....
> ... spin_lock(&kvm->mmu_lock) .....
> spin_unlock(&kvm->mmu_lock)
> kvm_arch_free_kvm()
> *** use after free of kvm ***
I don't understand this race ...
a piece of code in mmu_notifier_unregister() says:
/*
* Wait for any running method to finish, of course including
* ->release if it was run by mmu_notifier_release instead of us.
*/
synchronize_srcu(&srcu);
and code before that removes the notifier from the list, so it cannot be
called after we pass this point. mmu_notifier_release() does roughly
the same and explains it as:
/*
* synchronize_srcu here prevents mmu_notifier_release from returning to
* exit_mmap (which would proceed with freeing all pages in the mm)
* until the ->release method returns, if it was invoked by
* mmu_notifier_unregister.
*
* The mmu_notifier_mm can't go away from under us because one mm_count
* is held by exit_mmap.
*/
synchronize_srcu(&srcu);
The call of mmu_notifier->release is protected by srcu in both cases and
while it seems possible that mmu_notifier->release would be called
twice, I don't see a combination that could result in use-after-free
from mmu_notifier_release after mmu_notifier_unregister() has returned.
Doesn't [2/2] solve the exact same issue (that the release method cannot
be called twice in parallel)?
Thanks.
WARNING: multiple messages have this Message-ID (diff)
From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: pbonzini@redhat.com, christoffer.dall@linaro.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
marc.zyngier@arm.com, mark.rutland@arm.com,
andreyknvl@google.com
Subject: Re: [PATCH 1/2] kvm: Fix mmu_notifier release race
Date: Tue, 25 Apr 2017 20:49:05 +0200 [thread overview]
Message-ID: <20170425184904.GI5713@potion> (raw)
In-Reply-To: <1493028624-29837-2-git-send-email-suzuki.poulose@arm.com>
2017-04-24 11:10+0100, Suzuki K Poulose:
> The KVM uses mmu_notifier (wherever available) to keep track
> of the changes to the mm of the guest. The guest shadow page
> tables are released when the VM exits via mmu_notifier->ops.release().
> There is a rare chance that the mmu_notifier->release could be
> called more than once via two different paths, which could end
> up in use-after-free of kvm instance (such as [0]).
>
> e.g:
>
> thread A thread B
> ------- --------------
>
> get_signal-> kvm_destroy_vm()->
> do_exit-> mmu_notifier_unregister->
> exit_mm-> kvm_arch_flush_shadow_all()->
> exit_mmap-> spin_lock(&kvm->mmu_lock)
> mmu_notifier_release-> ....
> kvm_arch_flush_shadow_all()-> .....
> ... spin_lock(&kvm->mmu_lock) .....
> spin_unlock(&kvm->mmu_lock)
> kvm_arch_free_kvm()
> *** use after free of kvm ***
I don't understand this race ...
a piece of code in mmu_notifier_unregister() says:
/*
* Wait for any running method to finish, of course including
* ->release if it was run by mmu_notifier_release instead of us.
*/
synchronize_srcu(&srcu);
and code before that removes the notifier from the list, so it cannot be
called after we pass this point. mmu_notifier_release() does roughly
the same and explains it as:
/*
* synchronize_srcu here prevents mmu_notifier_release from returning to
* exit_mmap (which would proceed with freeing all pages in the mm)
* until the ->release method returns, if it was invoked by
* mmu_notifier_unregister.
*
* The mmu_notifier_mm can't go away from under us because one mm_count
* is held by exit_mmap.
*/
synchronize_srcu(&srcu);
The call of mmu_notifier->release is protected by srcu in both cases and
while it seems possible that mmu_notifier->release would be called
twice, I don't see a combination that could result in use-after-free
from mmu_notifier_release after mmu_notifier_unregister() has returned.
Doesn't [2/2] solve the exact same issue (that the release method cannot
be called twice in parallel)?
Thanks.
next prev parent reply other threads:[~2017-04-25 18:46 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-24 10:10 [PATCH 0/2] kvm: Fixes for race conditions Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-24 10:10 ` [PATCH 1/2] kvm: Fix mmu_notifier release race Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-25 15:37 ` Christoffer Dall
2017-04-25 15:37 ` Christoffer Dall
2017-04-25 15:37 ` Christoffer Dall
2017-04-25 18:49 ` Radim Krčmář [this message]
2017-04-25 18:49 ` Radim Krčmář
2017-04-25 18:49 ` Radim Krčmář
2017-04-26 16:03 ` Suzuki K Poulose
2017-04-26 16:03 ` Suzuki K Poulose
2017-04-26 16:17 ` Paul E. McKenney
2017-04-26 16:17 ` Paul E. McKenney
2017-04-28 17:20 ` Suzuki K Poulose
2017-04-28 17:20 ` Suzuki K Poulose
2017-04-28 17:20 ` Suzuki K Poulose
2017-05-03 13:13 ` Suzuki K Poulose
2017-05-03 13:13 ` Suzuki K Poulose
2017-05-03 13:13 ` Suzuki K Poulose
2017-04-24 10:10 ` [PATCH 2/2] kvm: arm/arm64: Fix race in resetting stage2 PGD Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-24 10:10 ` Suzuki K Poulose
2017-04-24 12:27 ` Christoffer Dall
2017-04-24 12:27 ` Christoffer Dall
2017-04-24 12:27 ` Christoffer Dall
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=20170425184904.GI5713@potion \
--to=rkrcmar@redhat.com \
--cc=andreyknvl@google.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=pbonzini@redhat.com \
--cc=suzuki.poulose@arm.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.