|
@@ -359,6 +359,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
|
struct vm_area_struct *vma, *prev;
|
|
struct vm_area_struct *vma, *prev;
|
|
int error = -EINVAL;
|
|
int error = -EINVAL;
|
|
const int grows = prot & (PROT_GROWSDOWN|PROT_GROWSUP);
|
|
const int grows = prot & (PROT_GROWSDOWN|PROT_GROWSUP);
|
|
|
|
+ const bool rier = (current->personality & READ_IMPLIES_EXEC) &&
|
|
|
|
+ (prot & PROT_READ);
|
|
|
|
+
|
|
prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP);
|
|
prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP);
|
|
if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */
|
|
if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -375,11 +378,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
reqprot = prot;
|
|
reqprot = prot;
|
|
- /*
|
|
|
|
- * Does the application expect PROT_READ to imply PROT_EXEC:
|
|
|
|
- */
|
|
|
|
- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
|
|
|
|
- prot |= PROT_EXEC;
|
|
|
|
|
|
|
|
down_write(¤t->mm->mmap_sem);
|
|
down_write(¤t->mm->mmap_sem);
|
|
|
|
|
|
@@ -414,6 +412,10 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
|
|
|
|
|
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
|
|
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
|
|
|
|
|
|
|
|
+ /* Does the application expect PROT_READ to imply PROT_EXEC */
|
|
|
|
+ if (rier && (vma->vm_flags & VM_MAYEXEC))
|
|
|
|
+ prot |= PROT_EXEC;
|
|
|
|
+
|
|
newflags = calc_vm_prot_bits(prot, pkey);
|
|
newflags = calc_vm_prot_bits(prot, pkey);
|
|
newflags |= (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
|
|
newflags |= (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
|
|
|
|
|
|
@@ -445,6 +447,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
|
|
error = -ENOMEM;
|
|
error = -ENOMEM;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
+ prot = reqprot;
|
|
}
|
|
}
|
|
out:
|
|
out:
|
|
up_write(¤t->mm->mmap_sem);
|
|
up_write(¤t->mm->mmap_sem);
|