CVE-2022-50014

Severity CVSS v4.0:
Pending analysis
Type:
CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Publication date:
18/06/2025
Last modified:
14/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> mm/gup: fix FOLL_FORCE COW security issue and remove FOLL_COW<br /> <br /> Ever since the Dirty COW (CVE-2016-5195) security issue happened, we know<br /> that FOLL_FORCE can be possibly dangerous, especially if there are races<br /> that can be exploited by user space.<br /> <br /> Right now, it would be sufficient to have some code that sets a PTE of a<br /> R/O-mapped shared page dirty, in order for it to erroneously become<br /> writable by FOLL_FORCE. The implications of setting a write-protected PTE<br /> dirty might not be immediately obvious to everyone.<br /> <br /> And in fact ever since commit 9ae0f87d009c ("mm/shmem: unconditionally set<br /> pte dirty in mfill_atomic_install_pte"), we can use UFFDIO_CONTINUE to map<br /> a shmem page R/O while marking the pte dirty. This can be used by<br /> unprivileged user space to modify tmpfs/shmem file content even if the<br /> user does not have write permissions to the file, and to bypass memfd<br /> write sealing -- Dirty COW restricted to tmpfs/shmem (CVE-2022-2590).<br /> <br /> To fix such security issues for good, the insight is that we really only<br /> need that fancy retry logic (FOLL_COW) for COW mappings that are not<br /> writable (!VM_WRITE). And in a COW mapping, we really only broke COW if<br /> we have an exclusive anonymous page mapped. If we have something else<br /> mapped, or the mapped anonymous page might be shared (!PageAnonExclusive),<br /> we have to trigger a write fault to break COW. If we don&amp;#39;t find an<br /> exclusive anonymous page when we retry, we have to trigger COW breaking<br /> once again because something intervened.<br /> <br /> Let&amp;#39;s move away from this mandatory-retry + dirty handling and rely on our<br /> PageAnonExclusive() flag for making a similar decision, to use the same<br /> COW logic as in other kernel parts here as well. In case we stumble over<br /> a PTE in a COW mapping that does not map an exclusive anonymous page, COW<br /> was not properly broken and we have to trigger a fake write-fault to break<br /> COW.<br /> <br /> Just like we do in can_change_pte_writable() added via commit 64fe24a3e05e<br /> ("mm/mprotect: try avoiding write faults for exclusive anonymous pages<br /> when changing protection") and commit 76aefad628aa ("mm/mprotect: fix<br /> soft-dirty check in can_change_pte_writable()"), take care of softdirty<br /> and uffd-wp manually.<br /> <br /> For example, a write() via /proc/self/mem to a uffd-wp-protected range has<br /> to fail instead of silently granting write access and bypassing the<br /> userspace fault handler. Note that FOLL_FORCE is not only used for debug<br /> access, but also triggered by applications without debug intentions, for<br /> example, when pinning pages via RDMA.<br /> <br /> This fixes CVE-2022-2590. Note that only x86_64 and aarch64 are<br /> affected, because only those support CONFIG_HAVE_ARCH_USERFAULTFD_MINOR.<br /> <br /> Fortunately, FOLL_COW is no longer required to handle FOLL_FORCE. So<br /> let&amp;#39;s just get rid of it.<br /> <br /> Thanks to Nadav Amit for pointing out that the pte_dirty() check in<br /> FOLL_FORCE code is problematic and might be exploitable.<br /> <br /> Note 1: We don&amp;#39;t check for the PTE being dirty because it doesn&amp;#39;t matter<br /> for making a "was COWed" decision anymore, and whoever modifies the<br /> page has to set the page dirty either way.<br /> <br /> Note 2: Kernels before extended uffd-wp support and before<br /> PageAnonExclusive (

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 5.19.6 (excluding)
cpe:2.3:o:linux:linux_kernel:6.0:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.0:rc2:*:*:*:*:*:*