Re: [PATCH v2] userfaultfd: release page in error path to avoid BUG_ON

From: Peter Xu
Date: Wed Apr 28 2021 - 20:08:51 EST


On Wed, Apr 28, 2021 at 04:08:58PM -0700, Axel Rasmussen wrote:
> Consider the following sequence of events:
>
> 1. Userspace issues a UFFD ioctl, which ends up calling into
> shmem_mfill_atomic_pte(). We successfully account the blocks, we
> shmem_alloc_page(), but then the copy_from_user() fails. We return
> -ENOENT. We don't release the page we allocated.
> 2. Our caller detects this error code, tries the copy_from_user() after
> dropping the mmap_lock, and retries, calling back into
> shmem_mfill_atomic_pte().
> 3. Meanwhile, let's say another process filled up the tmpfs being used.
> 4. So shmem_mfill_atomic_pte() fails to account blocks this time, and
> immediately returns - without releasing the page.
>
> This triggers a BUG_ON in our caller, which asserts that the page
> should always be consumed, unless -ENOENT is returned.
>
> To fix this, detect if we have such a "dangling" page when accounting
> fails, and if so, release it before returning.
>
> Fixes: cb658a453b93 ("userfaultfd: shmem: avoid leaking blocks and used blocks in UFFDIO_COPY")
> Reported-by: Hugh Dickins <hughd@xxxxxxxxxx>
> Signed-off-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx>

Reviewed-by: Peter Xu <peterx@xxxxxxxxxx>

Thanks,

--
Peter Xu