Re: [PATCH v2] mm/vma: keep the unlinked VMA off the file across unmap on mmap hook failure

From: Andrew Morton

Date: Wed Oct 07 2026 - 17:53:36 EST


On Wed, 7 Oct 2026 21:47:08 +0200 Oleg Keri <okerixx@xxxxxxxxx> wrote:

> Since commit 2ceb21171dd9 ("mm: consistently validate VMA state after
> mmap[_prepare] hooks"), the mmap error path clears vma->vm_file only
> after unmap_region(), so free_pgtables() unlinks the never-linked VMA
> and drops i_mmap_writable. Once it goes negative, every later shared
> writable mmap of that file fails with -EPERM until reboot.
>
> Clear vm_file across unmap_region() only, so that free_pgtables() does
> not unlink a VMA that was never linked to the file, and restore it for
> vma_close(): when the hook succeeded and the validation failed, the
> driver's close() still runs and may use vma->vm_file.
>
> ...
>
> Seen on next-20261006: one refused PCM mmap probe from alsa-lib left the
> device unmappable, so PipeWire could not play anything.

Thanks.

> --- a/mm/vma.c
> +++ b/mm/vma.c
> @@ -2616,12 +2616,15 @@ static int __mmap_new_file_vma(struct mmap_state *map,
> map->vm_file = vma->vm_file;
>
> if (error) {
> + struct file *file = vma->vm_file;
> UNMAP_STATE(unmap, vmi, vma, vma->vm_start, vma->vm_end,
> map->prev, map->next);
>
> + vma->vm_file = NULL;
> vma_iter_set(vmi, vma->vm_end);
> /* Undo any partial mapping done by a device driver. */
> unmap_region(&unmap);
> + vma->vm_file = file;
> /* Only safe once unmapped. */
> vma_close(vma);

Signaling the unmap code in this fashion and the effect of this on
__zap_vma_range()'s uprobe_munmap() ->vm_file test needs thinking
about. Perhaps a new bool in unmap_desc would be better.

But that's why we have Lorenzo. I'll queue this for now to keep
linux-next happier.