Re: [PATCH] futex: Prevent robust futex exit race more
From: Christian Brauner
Date: Thu Jul 23 2026 - 08:54:47 EST
On Wed, Jul 22, 2026 at 04:21:12PM +0200, Thomas Gleixner wrote:
> On Tue, Jul 21 2026 at 12:50, Keno Fischer wrote:
> > On Tue, 21 Jul 2026 14:24:34 +0200, Thomas Gleixner <tglx@xxxxxxxxxx> wrote:
> >> On Mon, Jul 20 2026 at 23:26, Keno Fischer wrote:
> >>> Fix this by augmenting the robust list exit processing to also
> >>> perform the extra wakeup if the futex word is owned by another
> >>> thread but FUTEX_WAITERS is *NOT* set.
> >>
> >> While your change "fixes" this particular problem, it leaves the related
> >> UAF problem unsolved.
> >>
> >> The more complete solution is:
> >>
> >> https://lore.kernel.org/all/20260602084648.462672743@xxxxxxxxxx/
> >>
> >> which is upstream now. Specifically the combined unlock/wake part
> >>
> >> https://lore.kernel.org/all/20260602090535.670514505@xxxxxxxxxx/
> >>
> >> ensures that your scenario can't happen and provides at the same time
> >> one part of the solution for the UAF exit race.
> >
> > Yes, I'm aware of that patch series.
> > However, this is not quite the same race.
> > As the updated comment indicates, the combined unlock/wake prevents one
> > of the three race scenarios that causes problems.
> > However, if a *woken up* task dies before it can re-acquire the futex,
> > the kernel must still pass the baton down the line to the next task.
> > The existing code handled this case for the scenario where there was no
> > interfering third task (the second scenario in the original comment).
> > However, the possibility that a third task could perform an uncontested
> > acquire in the meantime was not accounted for.
>
> Which means that the handling of the FUTEX_WAITER bit for robust non-PI
> futexes in the unlock path is inconsistent, which means the
> unconditional store 0 is the real problem.
>
> We should rather fix that than hacking around it in the exit handling
> code.
>
> Let me think about it some more.
>
> >>> This issues was discovered as part of a larger attempt to resolve the
> >>> long-standing issue that robust futexes are not safely usable across
> >>> pid namespaces.
> >>
> >> What's the actual problem with that?
> >
> > I was planning to write it up with that patch series, but here's
> > the abbreviated version: Embedded databases (e.g. LMBD) use
> > shared-memory robust mutexes (glibc pthread_mutex in the LMDB case)
> > to coordinate access to the database file among users. However, if
> > those users are in different pid namespaces, the mutex silently fails
> > to provide mutual exclusion, causing corruption and hangs (bad for a
> > database).
>
> Unsurprisingly a robust futex depends on unique PIDs, which are not
> obviously not guaranteed accross multiple PID namespaces.
Fwiw, I added unique inode numbers for the lifetime of the system to
pidfds some time ago. The inode number is allocated for every struct pid
and available via pid->ino. A pidfd can be stat()ed to retrieve it. Just
mentioning it in case this may be useful.