FAILED: patch "[PATCH] device-dax: implement ->split() to catch invalid munmap" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
9702cffdbf2129516db679e4467db81e1cd287daMon Sep 17 00:00:00 2001
From: Dan Williams <[email protected]>
Date: Wed, 29 Nov 2017 16:10:32 -0800
Subject: [PATCH] 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/0x30drivers/dax/device.c +12 -0
@@ -428,9 +428,21 @@ static int dev_dax_fault(struct vm_fault *vmf)return dev_dax_huge_fault (vmf,PE_SIZE_PTE ); } +static int dev_dax_split (struct vm_area_struct *vma,unsigned long addr) +{ +struct file *filp = vma->vm_file; +struct dev_dax *dev_dax = filp->private_data; +struct dax_region *dax_region = dev_dax->region; + +if (!IS_ALIGNED (addr, dax_region->align)) +return -EINVAL ; +return 0 ; +} +static const struct vm_operations_struct dax_vm_ops = { .fault = dev_dax_fault, .huge_fault = dev_dax_huge_fault, + .split = dev_dax_split, };static int dax_mmap (struct file *filp,struct vm_area_struct *vma)