On 08/02/2018 02:32 AM, Zhang,Yi wrote: > > > On 2018年08月02日 03:40, Dave Jiang wrote: >> >> On 07/31/2018 04:46 AM, Zhang Yi wrote: >>> It should be prevent user map an illegal vma range which larger than >>> dax device phiscal resourse, as we don't have swap logic while page >>> faulting in dax device. >> This patch prevents a user mapping an illegal vma range that is larger >> than a dax device physical resource. >> >>> Applications, especailly qemu, map the /dev/dax for virtual nvdimm's >>> backend device, we defined the v-nvdimm label area at the end of mapped >>> rang. By using an illegal size that exceeds the physical resource of >>> /dev/dax, then it will triger qemu a signal fault while accessing these >>> label area. >> When qemu maps the dax device for virtual nvdimm's backend device, the >> v-nvdimm label area is defined at the end of mapped range. By using an >> illegal size that exceeds the range of the device dax, it will trigger a >> fault with qemu. > Thanks Dava, that's could be much better. >> >>> Signed-off-by: Zhang Yi <[email protected]> >>> --- >>> drivers/dax/device.c | 28 ++++++++++++++++++++++++++++ >>> 1 file changed, 28 insertions(+) >>> >>> diff --git a/drivers/dax/device.c b/drivers/dax/device.c >>> index aff2c15..c9a50cd 100644 >>> --- a/drivers/dax/device.c >>> +++ b/drivers/dax/device.c >>> @@ -177,6 +177,32 @@ static const struct attribute_group >>> *dax_attribute_groups[] = { >>> NULL, >>> }; >>> >>> +static int check_vma_range(struct dev_dax *dev_dax, struct vm_area_struct >>> *vma, >>> + const char *func) >>> +{ >>> + struct device *dev = &dev_dax->dev; >>> + struct resource *res; >>> + unsigned long size; >>> + int ret, i; >>> + >>> + if (!dax_alive(dev_dax->dax_dev)) >>> + return -ENXIO; >>> + >>> + size = vma->vm_end - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT); >>> + ret = -EINVAL; >>> + for (i = 0; i < dev_dax->num_resources; i++) { >>> + res = &dev_dax->res[i]; >>> + if (size > resource_size(res)) { >>> + dev_info(dev, "%s: %s: fail, vma range is overflow\n", >>> + current->comm, func); >>> + ret = -EINVAL; >>> + continue; >>> + } else >>> + return 0; >>> + } >>> + return ret; >>> +} >>> + >>> static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, >>> const char *func) >>> { >>> @@ -465,6 +491,8 @@ static int dax_mmap(struct file *filp, struct >>> vm_area_struct *vma) >>> */ >>> id = dax_read_lock(); >>> rc = check_vma(dev_dax, vma, __func__); >>> + if (!rc) >>> + rc |= check_vma_range(dev_dax, vma, __func__);
I don't see any reason to logical or the return code. It should be 0, so you can just assign it to check_vma_range(). >> I think you want to augment check_vma() rather than adding another >> function? If this is added inside check_vma() then you can also skip the >> !dax_alive() check. Do you expect this function to be called anywhere else? > since check_vma range also will be called while dax page faulting. I > don't wanna this check_vma_range introduce some additional workload > while page fault. just let it checked in the mmap scenario Good point. Ok. >> >>> dax_read_unlock(id); >>> if (rc) >>> return rc; >>> > _______________________________________________ Linux-nvdimm mailing list [email protected] https://lists.01.org/mailman/listinfo/linux-nvdimm
