| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2024-49878: resource: fix region_intersects() vs add_memory_driver_managed() |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| resource: fix region_intersects() vs add_memory_driver_managed() |
| |
| On a system with CXL memory, the resource tree (/proc/iomem) related to |
| CXL memory may look like something as follows. |
| |
| 490000000-50fffffff : CXL Window 0 |
| 490000000-50fffffff : region0 |
| 490000000-50fffffff : dax0.0 |
| 490000000-50fffffff : System RAM (kmem) |
| |
| Because drivers/dax/kmem.c calls add_memory_driver_managed() during |
| onlining CXL memory, which makes "System RAM (kmem)" a descendant of "CXL |
| Window X". This confuses region_intersects(), which expects all "System |
| RAM" resources to be at the top level of iomem_resource. This can lead to |
| bugs. |
| |
| For example, when the following command line is executed to write some |
| memory in CXL memory range via /dev/mem, |
| |
| $ dd if=data of=/dev/mem bs=$((1 << 10)) seek=$((0x490000000 >> 10)) count=1 |
| dd: error writing '/dev/mem': Bad address |
| 1+0 records in |
| 0+0 records out |
| 0 bytes copied, 0.0283507 s, 0.0 kB/s |
| |
| the command fails as expected. However, the error code is wrong. It |
| should be "Operation not permitted" instead of "Bad address". More |
| seriously, the /dev/mem permission checking in devmem_is_allowed() passes |
| incorrectly. Although the accessing is prevented later because ioremap() |
| isn't allowed to map system RAM, it is a potential security issue. During |
| command executing, the following warning is reported in the kernel log for |
| calling ioremap() on system RAM. |
| |
| ioremap on RAM at 0x0000000490000000 - 0x0000000490000fff |
| WARNING: CPU: 2 PID: 416 at arch/x86/mm/ioremap.c:216 __ioremap_caller.constprop.0+0x131/0x35d |
| Call Trace: |
| memremap+0xcb/0x184 |
| xlate_dev_mem_ptr+0x25/0x2f |
| write_mem+0x94/0xfb |
| vfs_write+0x128/0x26d |
| ksys_write+0xac/0xfe |
| do_syscall_64+0x9a/0xfd |
| entry_SYSCALL_64_after_hwframe+0x4b/0x53 |
| |
| The details of command execution process are as follows. In the above |
| resource tree, "System RAM" is a descendant of "CXL Window 0" instead of a |
| top level resource. So, region_intersects() will report no System RAM |
| resources in the CXL memory region incorrectly, because it only checks the |
| top level resources. Consequently, devmem_is_allowed() will return 1 |
| (allow access via /dev/mem) for CXL memory region incorrectly. |
| Fortunately, ioremap() doesn't allow to map System RAM and reject the |
| access. |
| |
| So, region_intersects() needs to be fixed to work correctly with the |
| resource tree with "System RAM" not at top level as above. To fix it, if |
| we found a unmatched resource in the top level, we will continue to search |
| matched resources in its descendant resources. So, we will not miss any |
| matched resources in resource tree anymore. |
| |
| In the new implementation, an example resource tree |
| |
| |------------- "CXL Window 0" ------------| |
| |-- "System RAM" --| |
| |
| will behave similar as the following fake resource tree for |
| region_intersects(, IORESOURCE_SYSTEM_RAM, ), |
| |
| |-- "System RAM" --||-- "CXL Window 0a" --| |
| |
| Where "CXL Window 0a" is part of the original "CXL Window 0" that |
| isn't covered by "System RAM". |
| |
| The Linux kernel CVE team has assigned CVE-2024-49878 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 5.4.285 with commit 333fbaf6864a4ca031367eb947961a1f3484d337 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 5.10.227 with commit 1d5f85f1b7db79c75c9e07d6571ce2a7bdf725c4 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 5.15.168 with commit 8a6fef7d22a1d952aed68584d3fcc0d018d2bdc3 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 6.1.113 with commit 4b90d2eb451b357681063ba4552b10b39d7ad885 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 6.6.55 with commit 393331e16ce205e036e58b3d8ca4ee2e635f21d9 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 6.10.14 with commit 06ff97a20b8c9e9d256b0d2c3e87f78f8ccea3de |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 6.11.3 with commit 927abc5b7d6d2c2e936bec5a2f71d9512c5e72f7 |
| Issue introduced in 5.1 with commit c221c0b0308fd01d9fb33a16f64d2fd95f8830a4 and fixed in 6.12 with commit b4afe4183ec77f230851ea139d91e5cf2644c68b |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2024-49878 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| kernel/resource.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/333fbaf6864a4ca031367eb947961a1f3484d337 |
| https://git.kernel.org/stable/c/1d5f85f1b7db79c75c9e07d6571ce2a7bdf725c4 |
| https://git.kernel.org/stable/c/8a6fef7d22a1d952aed68584d3fcc0d018d2bdc3 |
| https://git.kernel.org/stable/c/4b90d2eb451b357681063ba4552b10b39d7ad885 |
| https://git.kernel.org/stable/c/393331e16ce205e036e58b3d8ca4ee2e635f21d9 |
| https://git.kernel.org/stable/c/06ff97a20b8c9e9d256b0d2c3e87f78f8ccea3de |
| https://git.kernel.org/stable/c/927abc5b7d6d2c2e936bec5a2f71d9512c5e72f7 |
| https://git.kernel.org/stable/c/b4afe4183ec77f230851ea139d91e5cf2644c68b |