forked from mirrors/linux
		
	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: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									9f3419315f
								
							
						
					
					
						commit
						c462ac288f
					
				
					 3 changed files with 28 additions and 0 deletions
				
			
		|  | @ -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, | ||||||
| 		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, | ||||||
| 			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; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Catalin Marinas
						Catalin Marinas