* [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel
@ 2026-06-03 1:23 Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 1/2] arm64: io: Rename ioremap_prot() to __ioremap_prot() Xiangyu Chen
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Xiangyu Chen @ 2026-06-03 1:23 UTC (permalink / raw)
To: catalin.marinas, gregkh; +Cc: stable, will
Changes:
V1 -> V2: According to Catalin's review comment, using backport instead of reimplementing fix.
Verified on linux-6.12 with Yocto environment.
Verification code & script:
C code:
------
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
// Using QEMU RTC HW address
#define PHYSICAL_ADDR 0x09010000
#define MAP_SIZE 4096
int main() {
int i = 180;
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {
perror("failed to open /dev/mem");
return 1;
}
// Start map
void *map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PHYSICAL_ADDR);
if (map_base == MAP_FAILED) {
perror("failed to mmap");
close(fd);
return 1;
}
printf("Put those info to script PID:%d, VADDR:%p\n", getpid(), map_base);
// Keep running for script trigger the issue.
while(i > 0) {
sleep(1);
i--;
}
munmap(map_base, MAP_SIZE);
close(fd);
return 0;
}
------ End of C code ------
Python code:
-----------
python3 -c '
pid = 506
vaddr = 0x7f9de3f000
f = open(f"/proc/{pid}/mem", "rb")
f.seek(vaddr)
f.read(4)
'
------End of Python code------
Usage:
Ensure kernel enabled the CONFIG_ARM64_PAN and CONFIG_DEVMEM
Start Qemuarm64 with -cpu cortex-a55 -M virt, e.g.:
qemu-system-aarch64 \
-cpu cortex-a55 \
-M virt \
-m 2G \
-smp 2 \
-kernel ./arch/arm64/boot/Image \
-append "console=ttyAMA0 root=/dev/vda rw earlycon" \
-drive if=none,file=rootfs.img,id=hd0,format=raw \
-device virtio-blk-device,drive=hd0 \
-nographic
After enter the qemu, using cat /proc/iomem to get a vaild MMIO
address, here is using RTC address (#define PHYSICAL_ADDR 0x09010000).
Build the C code, put the binary to target qemu system and run it, the
C reproducer would output the PID and mapped address, here example pid
is 506 and virtual address is 0x7f9de3f000.
Fill pid and virtual address to python code, without fix, kernel would crash
with "Unable to handle kernel read from unreadable memory".
Based on crash info, pstate: 20400005 (... +PAN ...) and FSC = 0x0f: level 3 permission fault
Call trace:
[ 678.563102] __memcpy_fromio+0x50/0x98
[ 678.563436] __access_remote_vm+0x294/0x3a8
[ 678.563901] access_remote_vm+0x18/0x30
[ 678.564308] mem_rw+0x1e0/0x370
[ 678.564534] mem_read+0x1c/0x30
[ 678.564754] vfs_read+0xcc/0x2d0
[ 678.564975] ksys_read+0x7c/0x120
[ 678.565192] __arm64_sys_read+0x24/0x38
[ 678.565450] invoke_syscall+0x5c/0x138
[ 678.565729] el0_svc_common.constprop.0+0x48/0xf0
[ 678.566038] do_el0_svc+0x24/0x38
[ 678.566264] el0_svc+0x38/0x108
[ 678.566514] el0t_64_sync_handler+0x120/0x130
[ 678.566823] el0t_64_sync+0x190/0x198
....
The behavior is the same as description of
commit:8f098037139b ("arm64: io: Extract user memory type in ioremap_prot()")
Will Deacon (2):
arm64: io: Rename ioremap_prot() to __ioremap_prot()
arm64: io: Extract user memory type in ioremap_prot()
arch/arm64/include/asm/io.h | 24 +++++++++++++++++++-----
arch/arm64/kernel/acpi.c | 2 +-
arch/arm64/mm/ioremap.c | 7 +++----
3 files changed, 23 insertions(+), 10 deletions(-)
--
2.49.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 6.12.y 1/2] arm64: io: Rename ioremap_prot() to __ioremap_prot()
2026-06-03 1:23 [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
@ 2026-06-03 1:23 ` Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 2/2] arm64: io: Extract user memory type in ioremap_prot() Xiangyu Chen
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Xiangyu Chen @ 2026-06-03 1:23 UTC (permalink / raw)
To: catalin.marinas, gregkh; +Cc: stable, will
From: Will Deacon <will@kernel.org>
commit f6bf47ab32e0863df50f5501d207dcdddb7fc507 upstream.
Rename our ioremap_prot() implementation to __ioremap_prot() and convert
all arch-internal callers over to the new function.
ioremap_prot() remains as a #define to __ioremap_prot() for
generic_access_phys() and will be subsequently extended to handle user
permissions in 'prot'.
Cc: Zeng Heng <zengheng4@huawei.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
arch/arm64/include/asm/io.h | 7 ++++---
arch/arm64/kernel/acpi.c | 2 +-
arch/arm64/mm/ioremap.c | 7 +++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 1ada23a6ec19..e6ad41131d80 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -274,15 +274,16 @@ __iowrite64_copy(void __iomem *to, const void *from, size_t count)
typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size,
pgprot_t *prot);
int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook);
+void __iomem *__ioremap_prot(phys_addr_t phys, size_t size, pgprot_t prot);
#define ioremap_prot ioremap_prot
#define _PAGE_IOREMAP PROT_DEVICE_nGnRE
#define ioremap_wc(addr, size) \
- ioremap_prot((addr), (size), PROT_NORMAL_NC)
+ __ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_np(addr, size) \
- ioremap_prot((addr), (size), PROT_DEVICE_nGnRnE)
+ __ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))
/*
* io{read,write}{16,32,64}be() macros
@@ -303,7 +304,7 @@ static inline void __iomem *ioremap_cache(phys_addr_t addr, size_t size)
if (pfn_is_map_memory(__phys_to_pfn(addr)))
return (void __iomem *)__phys_to_virt(addr);
- return ioremap_prot(addr, size, PROT_NORMAL);
+ return __ioremap_prot(addr, size, __pgprot(PROT_NORMAL));
}
/*
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index e6f66491fbe9..a99476819e6b 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -379,7 +379,7 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
prot = __acpi_get_writethrough_mem_attribute();
}
}
- return ioremap_prot(phys, size, pgprot_val(prot));
+ return __ioremap_prot(phys, size, prot);
}
/*
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 6cc0b7e7eb03..1e4794a2af7d 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -14,11 +14,10 @@ int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook)
return 0;
}
-void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
- unsigned long prot)
+void __iomem *__ioremap_prot(phys_addr_t phys_addr, size_t size,
+ pgprot_t pgprot)
{
unsigned long last_addr = phys_addr + size - 1;
- pgprot_t pgprot = __pgprot(prot);
/* Don't allow outside PHYS_MASK */
if (last_addr & ~PHYS_MASK)
@@ -39,7 +38,7 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
return generic_ioremap_prot(phys_addr, size, pgprot);
}
-EXPORT_SYMBOL(ioremap_prot);
+EXPORT_SYMBOL(__ioremap_prot);
/*
* Must be called after early_fixmap_init
--
2.49.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 6.12.y 2/2] arm64: io: Extract user memory type in ioremap_prot()
2026-06-03 1:23 [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 1/2] arm64: io: Rename ioremap_prot() to __ioremap_prot() Xiangyu Chen
@ 2026-06-03 1:23 ` Xiangyu Chen
2026-06-03 8:32 ` [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Catalin Marinas
2026-06-04 0:05 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Xiangyu Chen @ 2026-06-03 1:23 UTC (permalink / raw)
To: catalin.marinas, gregkh; +Cc: stable, will
From: Will Deacon <will@kernel.org>
[ Upstream commit 8f098037139b294050053123ab2bc0f819d08932 ]
The only caller of ioremap_prot() outside of the generic ioremap()
implementation is generic_access_phys(), which passes a 'pgprot_t' value
determined from the user mapping of the target 'pfn' being accessed by
the kernel. On arm64, the 'pgprot_t' contains all of the non-address
bits from the pte, including the permission controls, and so we end up
returning a new user mapping from ioremap_prot() which faults when
accessed from the kernel on systems with PAN:
| Unable to handle kernel read from unreadable memory at virtual address ffff80008ea89000
| ...
| Call trace:
| __memcpy_fromio+0x80/0xf8
| generic_access_phys+0x20c/0x2b8
| __access_remote_vm+0x46c/0x5b8
| access_remote_vm+0x18/0x30
| environ_read+0x238/0x3e8
| vfs_read+0xe4/0x2b0
| ksys_read+0xcc/0x178
| __arm64_sys_read+0x4c/0x68
Extract only the memory type from the user 'pgprot_t' in ioremap_prot()
and assert that we're being passed a user mapping, to protect us against
any changes in future that may require additional handling. To avoid
falsely flagging users of ioremap(), provide our own ioremap() macro
which simply wraps __ioremap_prot().
Cc: Zeng Heng <zengheng4@huawei.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Fixes: 893dea9ccd08 ("arm64: Add HAVE_IOREMAP_PROT support")
Reported-by: Jinjiang Tu <tujinjiang@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
[ Modified ioremap_prot() parameter, using "unsigned long user_prot" instead of
"pgprot_t user_prot" to fix conflict with generic header ]
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
arch/arm64/include/asm/io.h | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index e6ad41131d80..46bd37707e08 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -276,10 +276,23 @@ typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size,
int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook);
void __iomem *__ioremap_prot(phys_addr_t phys, size_t size, pgprot_t prot);
-#define ioremap_prot ioremap_prot
+static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
+ unsigned long user_prot)
+{
+ pgprot_t prot;
+ pteval_t user_prot_val = pgprot_val(__pgprot(user_prot));
+
+ if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
+ return NULL;
-#define _PAGE_IOREMAP PROT_DEVICE_nGnRE
+ prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,
+ user_prot_val & PTE_ATTRINDX_MASK);
+ return __ioremap_prot(phys, size, prot);
+}
+#define ioremap_prot ioremap_prot
+#define ioremap(addr, size) \
+ __ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size) \
__ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_np(addr, size) \
--
2.49.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel
2026-06-03 1:23 [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 1/2] arm64: io: Rename ioremap_prot() to __ioremap_prot() Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 2/2] arm64: io: Extract user memory type in ioremap_prot() Xiangyu Chen
@ 2026-06-03 8:32 ` Catalin Marinas
2026-06-03 8:51 ` Xiangyu Chen
2026-06-04 0:05 ` Sasha Levin
3 siblings, 1 reply; 6+ messages in thread
From: Catalin Marinas @ 2026-06-03 8:32 UTC (permalink / raw)
To: Xiangyu Chen; +Cc: gregkh, stable, will
On Wed, Jun 03, 2026 at 09:23:12AM +0800, Xiangyu Chen wrote:
> Changes:
> V1 -> V2: According to Catalin's review comment, using backport instead of reimplementing fix.
[...]
> Will Deacon (2):
> arm64: io: Rename ioremap_prot() to __ioremap_prot()
> arm64: io: Extract user memory type in ioremap_prot()
The backports look fine, they are nearly identical to the upstream
commits apart from the pgprot_t and ptdesc_t types.
Thanks.
--
Catalin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel
2026-06-03 8:32 ` [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Catalin Marinas
@ 2026-06-03 8:51 ` Xiangyu Chen
0 siblings, 0 replies; 6+ messages in thread
From: Xiangyu Chen @ 2026-06-03 8:51 UTC (permalink / raw)
To: Catalin Marinas; +Cc: gregkh, stable, will
On 6/3/26 16:32, Catalin Marinas wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Wed, Jun 03, 2026 at 09:23:12AM +0800, Xiangyu Chen wrote:
>> Changes:
>> V1 -> V2: According to Catalin's review comment, using backport instead of reimplementing fix.
> [...]
>> Will Deacon (2):
>> arm64: io: Rename ioremap_prot() to __ioremap_prot()
>> arm64: io: Extract user memory type in ioremap_prot()
> The backports look fine, they are nearly identical to the upstream
> commits apart from the pgprot_t and ptdesc_t types.
Thanks. I will use these insights to backport the fix to kernel 6.6.
Once testing is complete, I will send the patch upstream.
Br,
Xiangyu
>
> Thanks.
>
> --
> Catalin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel
2026-06-03 1:23 [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
` (2 preceding siblings ...)
2026-06-03 8:32 ` [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Catalin Marinas
@ 2026-06-04 0:05 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-06-04 0:05 UTC (permalink / raw)
To: catalin.marinas, gregkh; +Cc: Sasha Levin, stable, will, Xiangyu Chen
> [PATCH v2 6.12.y 0/2] arm64: io: ioremap_prot() rename + extract user
> memory type (CVE-2026-23346)
> 1/2 arm64: io: Rename ioremap_prot() to __ioremap_prot()
> 2/2 arm64: io: Extract user memory type in ioremap_prot()
Both queued for 6.12.y, thanks (and thanks to Catalin for the review).
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-04 0:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03 1:23 [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 1/2] arm64: io: Rename ioremap_prot() to __ioremap_prot() Xiangyu Chen
2026-06-03 1:23 ` [PATCH v2 6.12.y 2/2] arm64: io: Extract user memory type in ioremap_prot() Xiangyu Chen
2026-06-03 8:32 ` [PATCH v2 6.12.y 0/2] proposal to fix CVE-2026-23346 on 6.12 or older kernel Catalin Marinas
2026-06-03 8:51 ` Xiangyu Chen
2026-06-04 0:05 ` Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox