title: userfaultfd: release page in error path to avoid BUG_ON
description: In the Linux kernel, the following vulnerability has been resolved:
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.
affected:
{
product: Linux
vendor: Linux
defaultStatus: unaffected
repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
versions:
version: cb658a453b93, lessThan: 319116227e52, status: affected, versionType: git
version: cb658a453b93, lessThan: 07c9b834c97d, status: affected, versionType: git
version: cb658a453b93, lessThan: b3f1731c6d7f, status: affected, versionType: git
version: cb658a453b93, lessThan: 140cfd998012, status: affected, versionType: git
version: cb658a453b93, lessThan: ad5312797303, status: affected, versionType: git
version: cb658a453b93, lessThan: 2d59a0ed8b26, status: affected, versionType: git
version: cb658a453b93, lessThan: 7ed9d238c7db, status: affected, versionType: git
}
{
product: Linux
vendor: Linux
defaultStatus: affected
repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
versions:
version: 4.11, status: affected
version: 0, lessThan: 4.11, status: unaffected, versionType: custom
version: 4.14.233, lessThanOrEqual: 4.14.*, status: unaffected, versionType: custom
version: 4.19.191, lessThanOrEqual: 4.19.*, status: unaffected, versionType: custom
version: 5.4.120, lessThanOrEqual: 5.4.*, status: unaffected, versionType: custom
version: 5.10.38, lessThanOrEqual: 5.10.*, status: unaffected, versionType: custom
version: 5.11.22, lessThanOrEqual: 5.11.*, status: unaffected, versionType: custom
version: 5.12.5, lessThanOrEqual: 5.12.*, status: unaffected, versionType: custom
version: 5.13, lessThanOrEqual: *, status: unaffected, versionType: original_commit_for_fix
}
