|
@@ -386,3 +386,37 @@ bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
|
|
|
|
|
|
return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute);
|
|
return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * We only want to enforce protection keys on the current thread because we
|
|
|
|
+ * effectively have no access to AMR/IAMR for other threads or any way to tell
|
|
|
|
+ * which AMR/IAMR in a threaded process we could use.
|
|
|
|
+ *
|
|
|
|
+ * So do not enforce things if the VMA is not from the current mm, or if we are
|
|
|
|
+ * in a kernel thread.
|
|
|
|
+ */
|
|
|
|
+static inline bool vma_is_foreign(struct vm_area_struct *vma)
|
|
|
|
+{
|
|
|
|
+ if (!current->mm)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ /* if it is not our ->mm, it has to be foreign */
|
|
|
|
+ if (current->mm != vma->vm_mm)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
|
|
|
|
+ bool execute, bool foreign)
|
|
|
|
+{
|
|
|
|
+ if (static_branch_likely(&pkey_disabled))
|
|
|
|
+ return true;
|
|
|
|
+ /*
|
|
|
|
+ * Do not enforce our key-permissions on a foreign vma.
|
|
|
|
+ */
|
|
|
|
+ if (foreign || vma_is_foreign(vma))
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ return pkey_access_permitted(vma_pkey(vma), write, execute);
|
|
|
|
+}
|