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
