CVE-2022-49067

powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit

published February 26, 2025

CVSS
—
EPSS
0%
Percentile
17.1
In the wild
Unconfirmed
What it is

In the Linux kernel, the following vulnerability has been resolved:

powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit

mpe: On 64-bit Book3E vmalloc space starts at 0x8000000000000000.

Because of the way __pa() works we have:

__pa(0x8000000000000000) == 0, and therefore

virt_to_pfn(0x8000000000000000) == 0, and therefore

virt_addr_valid(0x8000000000000000) == true

Which is wrong, virt_addr_valid() should be false for vmalloc space.

In fact all vmalloc addresses that alias with a valid PFN will return

true from virt_addr_valid(). That can cause bugs with hardened usercopy

as described below by Kefeng Wang:

When running ethtool eth0 on 64-bit Book3E, a BUG occurred:

usercopy: Kernel memory exposure attempt detected from SLUB object not in SLUB page?! (offset 0, size 1048)!

kernel BUG at mm/usercopy.c:99

...

usercopy_abort+0x64/0xa0 (unreliable)

__check_heap_object+0x168/0x190

__check_object_size+0x1a0/0x200

dev_ethtool+0x2494/0x2b20

dev_ioctl+0x5d0/0x770

sock_do_ioctl+0xf0/0x1d0

sock_ioctl+0x3ec/0x5a0

__se_sys_ioctl+0xf0/0x160

system_call_exception+0xfc/0x1f0

system_call_common+0xf8/0x200

The code shows below,

data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));

copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))

The data is alloced by vmalloc(), virt_addr_valid(ptr) will return true

on 64-bit Book3E, which leads to the panic.

As commit 4dd7554a6456 ("powerpc/64: Add VIRTUAL_BUG_ON checks for __va

and __pa addresses") does, make sure the virt addr above PAGE_OFFSET in

the virt_addr_valid() for 64-bit, also add upper limit check to make

sure the virt is below high_memory.

Meanwhile, for 32-bit PAGE_OFFSET is the virtual address of the start

of lowmem, high_memory is the upper low virtual address, the check is

suitable for 32-bit, this will fix the issue mentioned in commit

602946ec2f90 ("powerpc: Set max_mapnr correctly") too.

On 32-bit there is a similar problem with high memory, that was fixed in

commit 602946ec2f90 ("powerpc: Set max_mapnr correctly"), but that

commit breaks highmem and needs to be reverted.

We can't easily fix __pa(), we have code that relies on its current

behaviour. So for now add extra checks to virt_addr_valid().

For 64-bit Book3S the extra checks are not necessary, the combination of

virt_to_pfn() and pfn_valid() should yield the correct result, but they

are harmless.

[mpe: Add additional change log detail]

The record
Technical detail
CVSS
Not scored
CVSS v4.0
Not supplied
EPSS
0.00262 · 17.1th percentile
Published
2025-02-26T01:54Z
EPSS history
Timeline
  • 26 FEB 01:54Z
    powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
    cvelistv5