Re: [PATCH v1] mm/vmalloc: read vm_map_ram block regions from the requested offset

From: Andrew Morton

Date: Sat Oct 17 2026 - 15:53:02 EST


On Sat, 17 Oct 2026 11:41:20 -0400 Nickolai Zeldovich <nickolai@xxxxxxxxxxxxx> wrote:

> Reading a vm_map_ram() mapping through /proc/kcore returns the wrong
> memory for every page except the first page of the first used region in
> its vmap block. read_kcore_iter() calls vread_iter() one page at a
> time, so a root user reading a live system with drgn, crash or gdb gets
> that first page in place of every later page of the mapping, and in
> place of the zeroes of the unused pages after it. This affects every
> vm_map_ram() mapping that fits in a vmap block (up to BITS_PER_LONG
> pages): erofs and f2fs decompression buffers, videobuf2 vmalloc/dma-sg
> buffers, udmabuf vmaps, fuse readdir pages. Kernels since v6.3 are
> affected.
>
> vmap_ram_vread_iter() walks the used regions of the block and, for each
> region, zero-fills up to its start and then copies from
> start + offset_in_page(addr). A read starting in a later page of a
> region therefore copies the region's first page, and a read starting
> past the end of a region still copies from that region.
>
> Skip regions that end at or before addr, and copy from addr itself,
> i.e. use addr - start as the offset into the region.
>
> Tested on x86_64 by queueing a 29-page V4L2_MEMORY_USERPTR buffer on a
> vivid capture device, which videobuf2-vmalloc maps with vm_map_ram(),
> page i starting with "userptr page i", and reading every page of its
> vmap block through /proc/kcore. Before, all 1024 pages of the block
> read as page 0. After, pages 0..28 read back in order and the rest of
> the block carries no tag. With a second buffer in the same block and a
> 100-page buffer outside the block path, reads at unaligned offsets,
> across page and region boundaries, into and within the unused part of
> the block, and of the whole block return the true contents.

Thanks. The Sashiko review is annoyingly embargoed for 24hrs, but it
found a possibly-preexisting off-by-one which should also be fixed in
the context of this patch.

I'm working on some akpm review prompts (which incorporate Tejun's
prompts, Chris's prompts and some Sashiko things). Its summary:



The fix looks good, but there's an off-by-one in the new size
calculation:

> + size = (re - rs + 1) << PAGE_SHIFT;

for_each_set_bitrange() returns half-open ranges [rs, re), so re is the
first unset bit. The size should be (re - rs) << PAGE_SHIFT.

This matters because vb_free() clears the used_map bits before
unmapping the pages. A concurrent /proc/kcore read could therefore
copy the contents of a just-freed page instead of zero-filling it.

Please drop the +1. Otherwise, the change looks good to me.