Commit c462ac28 authored by Catalin Marinas's avatar Catalin Marinas

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
...@@ -108,6 +108,19 @@ static inline bool arch_validate_prot(unsigned long prot, unsigned long addr) ...@@ -108,6 +108,19 @@ static inline bool arch_validate_prot(unsigned long prot, unsigned long addr)
#define arch_validate_prot arch_validate_prot #define arch_validate_prot arch_validate_prot
#endif #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: * Optimisation macro. It is equivalent to:
* (x & bit1) ? bit2 : 0 * (x & bit1) ? bit2 : 0
......
...@@ -1812,6 +1812,15 @@ unsigned long mmap_region(struct file *file, unsigned long addr, ...@@ -1812,6 +1812,15 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
vma_set_anonymous(vma); 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); vma_link(mm, vma, prev, rb_link, rb_parent);
/* Once vma denies write, undo our temporary denial count */ /* Once vma denies write, undo our temporary denial count */
if (file) { if (file) {
......
...@@ -603,6 +603,12 @@ static int do_mprotect_pkey(unsigned long start, size_t len, ...@@ -603,6 +603,12 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
goto out; 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); error = security_file_mprotect(vma, reqprot, prot);
if (error) if (error)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment