Skip to content

Commit 3e49a86

Browse files
Alexei Starovoitovanakryiko
authored andcommitted
mm: Enforce VM_IOREMAP flag and range in ioremap_page_range.
There are various users of get_vm_area() + ioremap_page_range() APIs. Enforce that get_vm_area() was requested as VM_IOREMAP type and range passed to ioremap_page_range() matches created vm_area to avoid accidentally ioremap-ing into wrong address range. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/bpf/20240305030516.41519-2-alexei.starovoitov@gmail.com
1 parent 8f50d5c commit 3e49a86

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

mm/vmalloc.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,21 @@ static int vmap_range_noflush(unsigned long addr, unsigned long end,
307307
int ioremap_page_range(unsigned long addr, unsigned long end,
308308
phys_addr_t phys_addr, pgprot_t prot)
309309
{
310+
struct vm_struct *area;
310311
int err;
311312

313+
area = find_vm_area((void *)addr);
314+
if (!area || !(area->flags & VM_IOREMAP)) {
315+
WARN_ONCE(1, "vm_area at addr %lx is not marked as VM_IOREMAP\n", addr);
316+
return -EINVAL;
317+
}
318+
if (addr != (unsigned long)area->addr ||
319+
(void *)end != area->addr + get_vm_area_size(area)) {
320+
WARN_ONCE(1, "ioremap request [%lx,%lx) doesn't match vm_area [%lx, %lx)\n",
321+
addr, end, (long)area->addr,
322+
(long)area->addr + get_vm_area_size(area));
323+
return -ERANGE;
324+
}
312325
err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot),
313326
ioremap_max_page_shift);
314327
flush_cache_vmap(addr, end);

0 commit comments

Comments
 (0)