|
@@ -94,26 +94,27 @@ int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot, int pkey
|
|
|
*/
|
|
|
if (pkey != -1)
|
|
|
return pkey;
|
|
|
- /*
|
|
|
- * Look for a protection-key-drive execute-only mapping
|
|
|
- * which is now being given permissions that are not
|
|
|
- * execute-only. Move it back to the default pkey.
|
|
|
- */
|
|
|
- if (vma_is_pkey_exec_only(vma) &&
|
|
|
- (prot & (PROT_READ|PROT_WRITE))) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
+
|
|
|
/*
|
|
|
* The mapping is execute-only. Go try to get the
|
|
|
* execute-only protection key. If we fail to do that,
|
|
|
* fall through as if we do not have execute-only
|
|
|
- * support.
|
|
|
+ * support in this mm.
|
|
|
*/
|
|
|
if (prot == PROT_EXEC) {
|
|
|
pkey = execute_only_pkey(vma->vm_mm);
|
|
|
if (pkey > 0)
|
|
|
return pkey;
|
|
|
+ } else if (vma_is_pkey_exec_only(vma)) {
|
|
|
+ /*
|
|
|
+ * Protections are *not* PROT_EXEC, but the mapping
|
|
|
+ * is using the exec-only pkey. This mapping was
|
|
|
+ * PROT_EXEC and will no longer be. Move back to
|
|
|
+ * the default pkey.
|
|
|
+ */
|
|
|
+ return ARCH_DEFAULT_PKEY;
|
|
|
}
|
|
|
+
|
|
|
/*
|
|
|
* This is a vanilla, non-pkey mprotect (or we failed to
|
|
|
* setup execute-only), inherit the pkey from the VMA we
|