Commit c462ac28 authored by Catalin Marinas's avatar Catalin Marinas
Browse files

mm: Introduce arch_validate_flags()



Similarly to arch_validate_prot() called from do_mprotect_pkey(), an
architecture may need to sanity-check the new vm_flags.

Define a dummy function always returning true. In addition to
do_mprotect_pkey(), also invoke it from mmap_region() prior to updating
vma->vm_page_prot to allow the architecture code to veto potentially
inconsistent vm_flags.

Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Acked-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 9f341931
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -108,6 +108,19 @@ static inline bool arch_validate_prot(unsigned long prot, unsigned long addr)
#define arch_validate_prot arch_validate_prot
#endif

#ifndef arch_validate_flags
/*
 * This is called from mmap() and mprotect() with the updated vma->vm_flags.
 *
 * Returns true if the VM_* flags are valid.
 */
static inline bool arch_validate_flags(unsigned long flags)
{
	return true;
}
#define arch_validate_flags arch_validate_flags
#endif

/*
 * Optimisation macro.  It is equivalent to:
 *      (x & bit1) ? bit2 : 0
+9 −0
Original line number Diff line number Diff line
@@ -1812,6 +1812,15 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
		vma_set_anonymous(vma);
	}

	/* Allow architectures to sanity-check the vm_flags */
	if (!arch_validate_flags(vma->vm_flags)) {
		error = -EINVAL;
		if (file)
			goto unmap_and_free_vma;
		else
			goto free_vma;
	}

	vma_link(mm, vma, prev, rb_link, rb_parent);
	/* Once vma denies write, undo our temporary denial count */
	if (file) {
+6 −0
Original line number Diff line number Diff line
@@ -603,6 +603,12 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
			goto out;
		}

		/* Allow architectures to sanity-check the new flags */
		if (!arch_validate_flags(newflags)) {
			error = -EINVAL;
			goto out;
		}

		error = security_file_mprotect(vma, reqprot, prot);
		if (error)
			goto out;