All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Akihiko Odaki <akihiko.odaki@daynix.com>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Stefan Weil" <sw@weilnetz.de>, "Fabiano Rosas" <farosas@suse.de>,
	"Hailiang Zhang" <zhanghailiang@xfusion.com>,
	"Phil Dennis-Jordan" <phil@philjordan.eu>,
	qemu-devel@nongnu.org, devel@daynix.com,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: Re: [PATCH v3 01/10] futex: Check value after qemu_futex_wait()
Date: Wed, 14 May 2025 13:06:27 -0400	[thread overview]
Message-ID: <aCTNkxN9HMJ5FvR-@x1.local> (raw)
In-Reply-To: <b1b6574c-1ddb-4129-8a68-fe88f93caecd@daynix.com>

On Wed, May 14, 2025 at 04:34:33PM +0900, Akihiko Odaki wrote:
> On 2025/05/13 23:39, 'Peter Xu' via devel wrote:
> > On Sun, May 11, 2025 at 03:08:18PM +0900, Akihiko Odaki wrote:
> > > futex(2) - Linux manual page
> > > https://man7.org/linux/man-pages/man2/futex.2.html
> > > > Note that a wake-up can also be caused by common futex usage patterns
> > > > in unrelated code that happened to have previously used the futex
> > > > word's memory location (e.g., typical futex-based implementations of
> > > > Pthreads mutexes can cause this under some conditions).  Therefore,
> > > > callers should always conservatively assume that a return value of 0
> > > > can mean a spurious wake-up, and use the futex word's value (i.e.,
> > > > the user-space synchronization scheme) to decide whether to continue
> > > > to block or not.
> > 
> > I'm just curious - do you know when this will happen?
> > 
> > AFAIU, QEMU uses futex always on private mappings, internally futex does
> > use (mm, HVA) tuple to index a futex, afaict.  Hence, I don't see how it
> > can get spurious wakeups..  And _if_ it happens, since mm pointer can't
> > change it must mean the HVA of the futex word is reused, it sounds like an
> > UAF user bug to me instead.

[1]

> > 
> > I checked the man-pages git repo, this line was introduced in:
> > 
> > https://github.com/mkerrisk/man-pages/commit/4b35dc5dabcf356ce6dcb1f949f7b00e76c7587d
> > 
> > I also didn't see details yet in commit message on why that paragraph was
> > added.
> > 
> > And..
> > 
> > > 
> > > Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> > > ---
> > >   include/qemu/futex.h              |  9 +++++++++
> > >   tests/unit/test-aio-multithread.c |  4 +++-
> > >   util/qemu-thread-posix.c          | 28 ++++++++++++++++------------
> > >   3 files changed, 28 insertions(+), 13 deletions(-)
> > > 
> > > diff --git a/include/qemu/futex.h b/include/qemu/futex.h
> > > index 91ae88966e12..f57774005330 100644
> > > --- a/include/qemu/futex.h
> > > +++ b/include/qemu/futex.h
> > > @@ -24,6 +24,15 @@ static inline void qemu_futex_wake(void *f, int n)
> > >       qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0);
> > >   }
> > > +/*
> > > + * Note that a wake-up can also be caused by common futex usage patterns in
> > > + * unrelated code that happened to have previously used the futex word's
> > > + * memory location (e.g., typical futex-based implementations of Pthreads
> > > + * mutexes can cause this under some conditions).  Therefore, callers should
> > 
> > .. another thing that was unclear to me is, here it's mentioning "typical
> > futex-based implementations of pthreads mutexes..", but here
> > qemu_futex_wait() is using raw futex without any pthread impl.  Does it
> > also mean that this may not be applicable to whatever might cause a
> > spurious wakeup?
> 
> No. The man-page mentions "unrelated code that happened to have previously
> used the futex word's memory location", so it doesn't matter whether we use
> pthread here.
> 
> libpthread and even this QemuEvent follows the "common futex usage" so we
> should do what is written in the man page.
> 
> Unfortunately the man page does not describe the "common futex usage
> pattern". It looks like as follows:
> 
> Assume there are two threads, one atomic variable, and one futex.
> 
> Thread A does the following:
> A1. Read the atomic variable.
> A2. Go A5 if the atomic variable is zero.
> A3. Wait using the futex.
> A4. Go A1.
> A5. Free the atomic variable and the futex.
> 
> Thread B does the following:
> B1. Set the atomic variable to zero.
> B2. Wake up using the futex.
> 
> In this example, the execution may happen in the following order:
> B1 -> A1 -> A2 -> A5 -> B2
> 
> Here, B2 will cause a spurious wake up of QemuEvent if the freed memory gets
> reused for QemuEvent.

This is true.

Said that, if to follow my previous statement at [1] above, here I think A5
is the UAF bug I mentioned, trying to free the lock object with existing
user (Thread B) accessing the object.

IMHO, the userapp should make sure the object will never be freed if
there's any possible user of it, and that includes a waker like Thread B.

For futex, the futex word (which is the important bit here relevant to
possible spurious wakeups) is part of the lock object, hence if the lock
object isn't freed too early it won't ever get reused, and then there
should have no chance of spurious wakeups in the futex context.

Thanks,

-- 
Peter Xu



  reply	other threads:[~2025-05-14 17:07 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-11  6:08 [PATCH v3 00/10] Improve futex usage Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 01/10] futex: Check value after qemu_futex_wait() Akihiko Odaki
2025-05-13 14:39   ` Peter Xu
2025-05-14  7:34     ` Akihiko Odaki
2025-05-14 17:06       ` Peter Xu [this message]
2025-05-16  5:34         ` Akihiko Odaki
2025-05-16 14:53           ` Peter Xu
2025-05-17  5:01             ` Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 02/10] futex: Support Windows Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 03/10] futex: Replace __linux__ with CONFIG_LINUX Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 04/10] qemu-thread: Avoid futex abstraction for non-Linux Akihiko Odaki
2025-05-14  0:51   ` Paolo Bonzini
2025-05-14 12:57     ` Akihiko Odaki
2025-05-16 11:09       ` Paolo Bonzini
2025-05-16 12:58         ` Akihiko Odaki
2025-05-16 14:25           ` Paolo Bonzini
2025-05-17  5:40             ` Akihiko Odaki
2025-05-17 10:24               ` Paolo Bonzini
2025-05-17 16:30                 ` Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 05/10] qemu-thread: Use futex for QemuEvent on Windows Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 06/10] qemu-thread: Use futex if available for QemuLockCnt Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 07/10] migration: Replace QemuSemaphore with QemuEvent Akihiko Odaki
2025-05-13 19:13   ` Peter Xu
2025-05-14 12:36     ` Akihiko Odaki
2025-05-11  6:08 ` [PATCH v3 08/10] migration/colo: " Akihiko Odaki
2025-05-12 15:12   ` Fabiano Rosas
2025-05-11  6:08 ` [PATCH v3 09/10] migration/postcopy: " Akihiko Odaki
2025-05-12 15:12   ` Fabiano Rosas
2025-05-11  6:08 ` [PATCH v3 10/10] hw/display/apple-gfx: " Akihiko Odaki

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=aCTNkxN9HMJ5FvR-@x1.local \
    --to=peterx@redhat.com \
    --cc=akihiko.odaki@daynix.com \
    --cc=berrange@redhat.com \
    --cc=devel@daynix.com \
    --cc=farosas@suse.de \
    --cc=marcandre.lureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=phil@philjordan.eu \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sw@weilnetz.de \
    --cc=zhanghailiang@xfusion.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.