Re: [PATCH 1/2] mm/memfd: handle GUP pins more reliably when write-sealing

From: Lorenzo Stoakes (ARM)

Date: Wed Nov 04 2026 - 04:20:43 EST


On Tue, Nov 03, 2026 at 07:31:44PM +0100, David Hildenbrand (Arm) wrote:
> memfd_wait_for_pins() detects GUP references by comparing a folio's
> actual refcount with its expected refcount. As spelled out by
> folio_expected_ref_count(), obtaining the expected refcount when there
> can be concurrent folio (un)mapping is racy.
>
> So it is possible that a changing folio mapcount can race with our
> check for GUP references, and F_SEAL_WRITE might succeed even if there
> are some, allowing file contents to be modified after sealing.
>
> For folios with a reliable pincount, detect FOLL_PIN references using
> folio_maybe_dma_pinned() before falling back to the refcount comparison.
> For small folios without that, the 1024 pinning BIAS makes it very hard
> (although not impossible) to misguide the refcount comparison.
>
> This improves FOLL_PIN detection for folios with a pincount. Handling
> FOLL_GET and small folios requires a more fundamental change.
>
> Fortunately, most interfaces that allow for GUP'ing such pages use
> FOLL_PIN, in particular interfaces using FOLL_LONGTERM. However, we
> still have some FOLL_GET leftovers ...
>
> Fixes: 05f65b5c7090 ("shm: wait for pins to be released when sealing")
> Cc: stable@xxxxxxxxxxxxxxx
> Cc: Chris Mason <mason@xxxxxxxxxx>
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>

All very delicate stuff, I wonder if we could somehow make the logic here
generalised in a follow-up?

Anyway seems reasonable to me so:

Reviewed-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>

> ---
> mm/memfd.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/mm/memfd.c b/mm/memfd.c
> index 0f6fff004f5e4..9eda4c3eeaca5 100644
> --- a/mm/memfd.c
> +++ b/mm/memfd.c
> @@ -32,6 +32,13 @@
>
> static bool memfd_folio_has_extra_refs(struct folio *folio)
> {
> + /*
> + * Use the precise pincount where available to avoid racy refcount
> + * comparisons.
> + */
> + if (folio_has_pincount(folio) && folio_maybe_dma_pinned(folio))
> + return true;
> +
> return folio_ref_count(folio) != folio_expected_ref_count(folio);
> }
>
>
> --
> 2.43.0
>

--
Cheers, Lorenzo