Linux kernel -stable discussions
 help / color / mirror / Atom feed
* proposal to fix CVE-2026-23346 on 6.12 or older kernel
@ 2026-05-20  9:13 Xiangyu Chen
  2026-05-20  9:13 ` [PATCH 6.12 1/1] arm64: io: correct user memory type in ioremap_prot() Xiangyu Chen
  0 siblings, 1 reply; 4+ messages in thread
From: Xiangyu Chen @ 2026-05-20  9:13 UTC (permalink / raw)
  To: will; +Cc: catalin.marinas, stable, gregkh

Hi Will,

I am looking a CVE issue(CVE-2026-23346) on stable kernel. It was fixed by
commit:8f098037139b ("arm64: io: Extract user memory type in ioremap_prot()").

I have already reproduced it on 6.12 and 6.6 stable kernel[1], but
directly porting the upstream patch's macro changes inside <asm/io.h> creates
circular build dependencies due to the architecture-specific GENERIC_IOREMAP
refactoring introduced in the stable kernel lifecycle.

Since this issue was triggered by generic_access_phys() passes a 'pgprot_t'
value determined from the user mapping of the target 'pfn' being accessed by the kernel.
On arm64, this 'pgprot_t' contains all non-address bits from the pte, including user
permission controls (PTE_USER). When a process attempts to read the target memory via
cross-process subsystems (such as reading /proc/<pid>/mem or via ptrace), the kernel
re-maps this memory using ioremap_prot(). Since the PTE_USER bit is incorrectly preserved
in the temporary kernel-space mapping, it triggers a level 3 permission fault on systems
with PAN (Privileged Access Never) enabled, resulting in an immediate kernel panic.

To bypass header dependency traps safely, I have changed the backport code, this backport
confines the fix entirely inside the implementation layer of arch/arm64/mm/ioremap.c:
1. It uses pgprot_val() to safely unpack page properties into a pteval_t mask.
2. It introduces a targeted safety check (if (prot_val & PTE_USER)) to
   selectively strip away volatile user permission parameters.
3. It maps the memory through pure kernel attributes, leaving standard
   peripheral device drivers completely unaffected.

(see [PATCH 6.12 1/1] arm64: io: correct user memory type in ioremap_prot() ).
The code I have verified on qemuarm64, after applied the fix, crash won't happen anymore.

So, could you help to review, if we can use this solution to fix this CVE on an older stable
kernel? Thanks.


[1] Test steps:

1.1 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------

1.2 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()")


Thanks!

Br,
Xiangyu

Xiangyu Chen (1):
  arm64: io: correct user memory type in ioremap_prot()

 arch/arm64/mm/ioremap.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-05-20 17:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-20  9:13 proposal to fix CVE-2026-23346 on 6.12 or older kernel Xiangyu Chen
2026-05-20  9:13 ` [PATCH 6.12 1/1] arm64: io: correct user memory type in ioremap_prot() Xiangyu Chen
2026-05-20 11:17   ` Greg KH
2026-05-20 17:01   ` Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox