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

Commit 13575f86 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Michael Bestas
Browse files

UPSTREAM: mremap: don't allow MREMAP_DONTUNMAP on special_mappings and aio

As kernel expect to see only one of such mappings, any further operations
on the VMA-copy may be unexpected by the kernel.  Maybe it's being on the
safe side, but there doesn't seem to be any expected use-case for this, so
restrict it now.

Link: https://lkml.kernel.org/r/20201013013416.390574-4-dima@arista.com


Fixes: commit e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Ralph Campbell <rcampbell@nvidia.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
(cherry picked from commit cd544fd1dc9293c6702fab6effa63dac1cc67e99)

Bug: 176847609
Signed-off-by: default avatarKalesh Singh <kaleshsingh@google.com>
Change-Id: I9fc569e41bd7fc07c2a168c96d83eda0396c2305
parent 958bc1f5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1464,7 +1464,7 @@ static int pseudo_lock_dev_release(struct inode *inode, struct file *filp)
	return 0;
}

static int pseudo_lock_dev_mremap(struct vm_area_struct *area)
static int pseudo_lock_dev_mremap(struct vm_area_struct *area, unsigned long flags)
{
	/* Not supported */
	return -EINVAL;
+4 −1
Original line number Diff line number Diff line
@@ -320,13 +320,16 @@ static void aio_free_ring(struct kioctx *ctx)
	}
}

static int aio_ring_mremap(struct vm_area_struct *vma)
static int aio_ring_mremap(struct vm_area_struct *vma, unsigned long flags)
{
	struct file *file = vma->vm_file;
	struct mm_struct *mm = vma->vm_mm;
	struct kioctx_table *table;
	int i, res = -EINVAL;

	if (flags & MREMAP_DONTUNMAP)
		return -EINVAL;

	spin_lock(&mm->ioctx_lock);
	rcu_read_lock();
	table = rcu_dereference(mm->ioctx_table);
+1 −1
Original line number Diff line number Diff line
@@ -499,7 +499,7 @@ struct vm_operations_struct {
	void (*open)(struct vm_area_struct * area);
	void (*close)(struct vm_area_struct * area);
	int (*split)(struct vm_area_struct * area, unsigned long addr);
	int (*mremap)(struct vm_area_struct * area);
	int (*mremap)(struct vm_area_struct *area, unsigned long flags);
	vm_fault_t (*fault)(struct vm_fault *vmf);
	vm_fault_t (*huge_fault)(struct vm_fault *vmf,
			enum page_entry_size pe_size);
+5 −1
Original line number Diff line number Diff line
@@ -3492,10 +3492,14 @@ static const char *special_mapping_name(struct vm_area_struct *vma)
	return ((struct vm_special_mapping *)vma->vm_private_data)->name;
}

static int special_mapping_mremap(struct vm_area_struct *new_vma)
static int special_mapping_mremap(struct vm_area_struct *new_vma,
				  unsigned long flags)
{
	struct vm_special_mapping *sm = new_vma->vm_private_data;

	if (flags & MREMAP_DONTUNMAP)
		return -EINVAL;

	if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
		return -EFAULT;

+1 −1
Original line number Diff line number Diff line
@@ -577,7 +577,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
	if (moved_len < old_len) {
		err = -ENOMEM;
	} else if (vma->vm_ops && vma->vm_ops->mremap) {
		err = vma->vm_ops->mremap(new_vma);
		err = vma->vm_ops->mremap(new_vma, flags);
	}

	if (unlikely(err)) {