The patch titled Subject: userfaultfd: release page in error path to avoid BUG_ON has been removed from the -mm tree. Its filename was userfaultfd-release-page-in-error-path-to-avoid-bug_on.patch
This patch was dropped because it was merged into mainline or a subsystem tree
------------------------------------------------------ From: Axel Rasmussen axelrasmussen@google.com Subject: userfaultfd: release page in error path to avoid BUG_ON
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.
Link: https://lkml.kernel.org/r/20210428230858.348400-1-axelrasmussen@google.com Fixes: cb658a453b93 ("userfaultfd: shmem: avoid leaking blocks and used blocks in UFFDIO_COPY") Signed-off-by: Axel Rasmussen axelrasmussen@google.com Reported-by: Hugh Dickins hughd@google.com Acked-by: Hugh Dickins hughd@google.com Reviewed-by: Peter Xu peterx@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org ---
mm/shmem.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/mm/shmem.c~userfaultfd-release-page-in-error-path-to-avoid-bug_on +++ a/mm/shmem.c @@ -2361,8 +2361,18 @@ static int shmem_mfill_atomic_pte(struct pgoff_t offset, max_off;
ret = -ENOMEM; - if (!shmem_inode_acct_block(inode, 1)) + if (!shmem_inode_acct_block(inode, 1)) { + /* + * We may have got a page, returned -ENOENT triggering a retry, + * and now we find ourselves with -ENOMEM. Release the page, to + * avoid a BUG_ON in our caller. + */ + if (unlikely(*pagep)) { + put_page(*pagep); + *pagep = NULL; + } goto out; + }
if (!*pagep) { page = shmem_alloc_page(gfp, info, pgoff); _
Patches currently in -mm which might be from axelrasmussen@google.com are
userfaultfd-shmem-combine-shmem_mcopy_atomicmfill_zeropage_pte.patch userfaultfd-shmem-support-minor-fault-registration-for-shmem.patch userfaultfd-shmem-support-uffdio_continue-for-shmem.patch userfaultfd-shmem-advertise-shmem-minor-fault-support.patch userfaultfd-shmem-modify-shmem_mfill_atomic_pte-to-use-install_pte.patch userfaultfd-selftests-use-memfd_create-for-shmem-test-type.patch userfaultfd-selftests-create-alias-mappings-in-the-shmem-test.patch userfaultfd-selftests-reinitialize-test-context-in-each-test.patch userfaultfd-selftests-exercise-minor-fault-handling-shmem-support.patch
linux-stable-mirror@lists.linaro.org