You are right, thanks for catching this. pb[i].pfn is a Hyper-V PFN at 4K granularity, so passing it directly to pfn_to_page() is wrong where PAGE_SIZE > 4K, and it also drops the intra-page offset. Fixed in v2 by reconstructing the physical address and using phys_to_page() + offset_in_page(). Built for i386 (HIGHMEM) and arm64 (64K pages).
Thanks, Anton ср, 3 июн. 2026 г. в 18:53, <[email protected]>: > > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) > to consider: > - [Critical] Passing a Hyper-V PFN directly to `pfn_to_page()` causes > out-of-bounds memory accesses on architectures where `PAGE_SIZE > 4KB` (e.g., > ARM64 with 64KB pages), and loses the intra-page chunk offset. > -- > > commit a844fbf018cd37eedc9a1f0aea79d6235c00bec3 > Author: Anton Leontev <[email protected]> > > hv_netvsc: use kmap_local_page in netvsc_copy_to_send_buf > > This commit replaces phys_to_virt() with kmap_local_page() in > netvsc_copy_to_send_buf() to map skb fragment pages. This is intended to > fix a fatal transmit softirq fault on 32-bit x86 configurations with > HIGHMEM, where phys_to_virt() is only valid for LOWMEM addresses. > > > diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c > > index 59e95341f9b1e..6984f6c97257d 100644 > > --- a/drivers/net/hyperv/netvsc.c > > +++ b/drivers/net/hyperv/netvsc.c > > [ ... ] > > > @@ -965,11 +966,13 @@ static void netvsc_copy_to_send_buf(struct > > netvsc_device *net_device, > > } > > > > for (i = 0; i < page_count; i++) { > > - char *src = phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT); > > + struct page *page = pfn_to_page(pb[i].pfn); > > + char *src = kmap_local_page(page); > > [Severity: Critical] > Does this cause out-of-bounds memory accesses on architectures with a native > page size greater than 4KB? > > The pb[i].pfn field contains a Hyper-V PFN, which always operates at 4KB > granularity. Passing this directly to pfn_to_page() assumes it is a native > Linux PFN. > > On architectures where the native page size is larger than 4KB (such as > ARM64 with 64KB pages), the Hyper-V PFN is significantly larger than the > corresponding native Linux PFN. Using it with pfn_to_page() would return an > invalid struct page pointer. > > Calling kmap_local_page() on this invalid pointer in > netvsc_copy_to_send_buf() and subsequently reading from it could lead to > memory corruption, out-of-bounds accesses, or kernel panics. > > Could this also lose the native page offset of the original 4KB chunk within > the larger Linux page, resulting in an incorrect read offset during the > subsequent memcpy? > > > u32 offset = pb[i].offset; > > u32 len = pb[i].len; > > > > memcpy(dest, (src + offset), len); > > + kunmap_local(src); > > dest += len; > > } > > -- > Sashiko AI review · > https://sashiko.dev/#/patchset/[email protected]?part=1
