Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f98735c authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds
Browse files

vm audit: add VM_DONTEXPAND to mmap for drivers that need it



Drivers that register a ->fault handler, but do not range-check the
offset argument, must set VM_DONTEXPAND in the vm_flags in order to
prevent an expanding mremap from overflowing the resource.

I've audited the tree and attempted to fix these problems (usually by
adding VM_DONTEXPAND where it is not obvious).

Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fe2528b9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -506,6 +506,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
	vma->vm_ops = &drm_vm_dma_ops;

	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
	vma->vm_flags |= VM_DONTEXPAND;

	vma->vm_file = filp;	/* Needed for drm_vm_open() */
	drm_vm_open_locked(vma);
@@ -655,6 +656,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
		return -EINVAL;	/* This should never happen. */
	}
	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
	vma->vm_flags |= VM_DONTEXPAND;

	vma->vm_file = filp;	/* Needed for drm_vm_open() */
	drm_vm_open_locked(vma);
+1 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
	vdata->refcnt = ATOMIC_INIT(1);
	vma->vm_private_data = vdata;

	vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP);
	vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
	if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	vma->vm_ops = &mspec_vm_ops;
+0 −4
Original line number Diff line number Diff line
@@ -50,10 +50,6 @@ static int ncp_file_mmap_fault(struct vm_area_struct *area,
	pos = vmf->pgoff << PAGE_SHIFT;

	count = PAGE_SIZE;
	if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) {
		WARN_ON(1); /* shouldn't happen? */
		count = area->vm_end - (unsigned long)vmf->virtual_address;
	}
	/* what we can read in one go */
	bufsize = NCP_SERVER(inode)->buffer_size;

+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ static int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
		return -EINVAL;

	vma->vm_ops = &relay_file_mmap_ops;
	vma->vm_flags |= VM_DONTEXPAND;
	vma->vm_private_data = buf;
	buf->chan->cb->buf_mapped(buf, filp);

+1 −1
Original line number Diff line number Diff line
@@ -2216,7 +2216,7 @@ int install_special_mapping(struct mm_struct *mm,
	vma->vm_start = addr;
	vma->vm_end = addr + len;

	vma->vm_flags = vm_flags | mm->def_flags;
	vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);

	vma->vm_ops = &special_mapping_vmops;
Loading