Skip to content

Commit 9702cff

Browse files
djbwtorvalds
authored andcommitted
device-dax: implement ->split() to catch invalid munmap attempts
Similar to how device-dax enforces that the 'address', 'offset', and 'len' parameters to mmap() be aligned to the device's fundamental alignment, the same constraints apply to munmap(). Implement ->split() to fail munmap calls that violate the alignment constraint. Otherwise, we later fail VM_BUG_ON checks in the unmap_page_range() path with crash signatures of the form: vma ffff8800b60c8a88 start 00007f88c0000000 end 00007f88c0e00000 next (null) prev (null) mm ffff8800b61150c0 prot 8000000000000027 anon_vma (null) vm_ops ffffffffa0091240 pgoff 0 file ffff8800b638ef80 private_data (null) flags: 0x380000fb(read|write|shared|mayread|maywrite|mayexec|mayshare|softdirty|mixedmap|hugepage) ------------[ cut here ]------------ kernel BUG at mm/huge_memory.c:2014! [..] RIP: 0010:__split_huge_pud+0x12a/0x180 [..] Call Trace: unmap_page_range+0x245/0xa40 ? __vma_adjust+0x301/0x990 unmap_vmas+0x4c/0xa0 unmap_region+0xae/0x120 ? __vma_rb_erase+0x11a/0x230 do_munmap+0x276/0x410 vm_munmap+0x6a/0xa0 SyS_munmap+0x1d/0x30 Link: http://lkml.kernel.org/r/151130418681.4029.7118245855057952010.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: dee4107 ("/dev/dax, core: file operations and dax-mmap") Signed-off-by: Dan Williams <[email protected]> Reported-by: Jeff Moyer <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 31383c6 commit 9702cff

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

drivers/dax/device.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,21 @@ static int dev_dax_fault(struct vm_fault *vmf)
428428
return dev_dax_huge_fault(vmf, PE_SIZE_PTE);
429429
}
430430

431+
static int dev_dax_split(struct vm_area_struct *vma, unsigned long addr)
432+
{
433+
struct file *filp = vma->vm_file;
434+
struct dev_dax *dev_dax = filp->private_data;
435+
struct dax_region *dax_region = dev_dax->region;
436+
437+
if (!IS_ALIGNED(addr, dax_region->align))
438+
return -EINVAL;
439+
return 0;
440+
}
441+
431442
static const struct vm_operations_struct dax_vm_ops = {
432443
.fault = dev_dax_fault,
433444
.huge_fault = dev_dax_huge_fault,
445+
.split = dev_dax_split,
434446
};
435447

436448
static int dax_mmap(struct file *filp, struct vm_area_struct *vma)

0 commit comments

Comments
 (0)