X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=mm%2Fmprotect.c;h=653b8571c1ed10e86c94ae727147b77ce0e09788;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=05dc34246b20e29e46545af8e744c013d6f5ecfc;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/mm/mprotect.c b/mm/mprotect.c index 05dc34246..653b8571c 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -106,7 +105,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, struct mm_struct *mm = vma->vm_mm; unsigned long oldflags = vma->vm_flags; long nrpages = (end - start) >> PAGE_SHIFT; - unsigned long charged = 0, old_end = vma->vm_end; + unsigned long charged = 0; pgprot_t newprot; pgoff_t pgoff; int error; @@ -125,7 +124,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, * a MAP_NORESERVE private mapping to writable will now reserve. */ if (newflags & VM_WRITE) { - if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED))) { + if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) { charged = nrpages; if (security_vm_enough_memory(charged)) return -ENOMEM; @@ -167,12 +166,7 @@ success: */ vma->vm_flags = newflags; vma->vm_page_prot = newprot; - if (oldflags & VM_EXEC) - arch_remove_exec_range(current->mm, old_end); - if (is_vm_hugetlb_page(vma)) - hugetlb_change_protection(vma, start, end, newprot); - else - change_protection(vma, start, end, newprot); + change_protection(vma, start, end, newprot); vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); vm_stat_account(mm, newflags, vma->vm_file, nrpages); return 0; @@ -246,6 +240,11 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot) /* Here we know that vma->vm_start <= nstart < vma->vm_end. */ + if (is_vm_hugetlb_page(vma)) { + error = -EACCES; + goto out; + } + newflags = vm_flags | (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC)); /* newflags >> 4 shift VM_MAY% in place of VM_% */