Michal Suchanek 0f51cb
From cbe94edc1c062ba2f31e9d2432a374d17f25a002 Mon Sep 17 00:00:00 2001
Michal Suchanek 0f51cb
From: Russell Currey <ruscur@russell.cc>
Michal Suchanek 0f51cb
Date: Fri, 10 Mar 2023 16:08:34 +1100
Michal Suchanek 0f51cb
Subject: [PATCH] powerpc/mm: Fix false detection of read faults
Michal Suchanek 0f51cb
MIME-Version: 1.0
Michal Suchanek 0f51cb
Content-Type: text/plain; charset=UTF-8
Michal Suchanek 0f51cb
Content-Transfer-Encoding: 8bit
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
Patch-mainline: submitted http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20230310050834.63105-1-ruscur@russell.cc/
Michal Suchanek 0f51cb
References: bsc#1208864
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
To support detection of read faults with Radix execute-only memory, the
Michal Suchanek 0f51cb
vma_is_accessible() check in access_error() (which checks for PROT_NONE)
Michal Suchanek 0f51cb
was replaced with a check to see if VM_READ was missing, and if so,
Michal Suchanek 0f51cb
returns true to assert the fault was caused by a bad read.
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
This is incorrect, as it ignores that both VM_WRITE and VM_EXEC imply
Michal Suchanek 0f51cb
read on powerpc, as defined in protection_map[].  This causes mappings
Michal Suchanek 0f51cb
containing VM_WRITE or VM_EXEC without VM_READ to misreport the cause of
Michal Suchanek 0f51cb
page faults, since the MMU is still allowing reads.
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
Correct this by restoring the original vma_is_accessible() check for
Michal Suchanek 0f51cb
PROT_NONE mappings, and adding a separate check for Radix PROT_EXEC-only
Michal Suchanek 0f51cb
mappings.
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
Fixes: 395cac7752b9 ("powerpc/mm: Support execute-only memory on the Radix MMU")
Michal Suchanek 0f51cb
Reported-by: Michal Suchánek <msuchanek@suse.de>
Michal Suchanek 0f51cb
Tested-by: Benjamin Gray <bgray@linux.ibm.com>
Michal Suchanek 0f51cb
Signed-off-by: Russell Currey <ruscur@russell.cc>
Michal Suchanek 0f51cb
Acked-by: Michal Suchanek <msuchanek@suse.de>
Michal Suchanek 0f51cb
---
Michal Suchanek 0f51cb
 arch/powerpc/mm/fault.c | 11 ++++++++---
Michal Suchanek 0f51cb
 1 file changed, 8 insertions(+), 3 deletions(-)
Michal Suchanek 0f51cb
Michal Suchanek 0f51cb
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
Michal Suchanek 0f51cb
index 2bef19cc1b98..af46aa88422b 100644
Michal Suchanek 0f51cb
--- a/arch/powerpc/mm/fault.c
Michal Suchanek 0f51cb
+++ b/arch/powerpc/mm/fault.c
Michal Suchanek 0f51cb
@@ -271,11 +271,16 @@ static bool access_error(bool is_write, bool is_exec, struct vm_area_struct *vma
Michal Suchanek 0f51cb
 	}
Michal Suchanek 0f51cb
 
Michal Suchanek 0f51cb
 	/*
Michal Suchanek 0f51cb
-	 * Check for a read fault.  This could be caused by a read on an
Michal Suchanek 0f51cb
-	 * inaccessible page (i.e. PROT_NONE), or a Radix MMU execute-only page.
Michal Suchanek 0f51cb
+	 * VM_READ, VM_WRITE and VM_EXEC all imply read permissions, as
Michal Suchanek 0f51cb
+	 * defined in protection_map[].  Read faults can only be caused by
Michal Suchanek 0f51cb
+	 * a PROT_NONE mapping, or with a PROT_EXEC-only mapping on Radix.
Michal Suchanek 0f51cb
 	 */
Michal Suchanek 0f51cb
-	if (unlikely(!(vma->vm_flags & VM_READ)))
Michal Suchanek 0f51cb
+	if (unlikely(!vma_is_accessible(vma)))
Michal Suchanek 0f51cb
 		return true;
Michal Suchanek 0f51cb
+
Michal Suchanek 0f51cb
+	if (unlikely(radix_enabled() && ((vma->vm_flags & VM_ACCESS_FLAGS) == VM_EXEC)))
Michal Suchanek 0f51cb
+		return true;
Michal Suchanek 0f51cb
+
Michal Suchanek 0f51cb
 	/*
Michal Suchanek 0f51cb
 	 * We should ideally do the vma pkey access check here. But in the
Michal Suchanek 0f51cb
 	 * fault path, handle_mm_fault() also does the same check. To avoid
Michal Suchanek 0f51cb
-- 
Michal Suchanek 0f51cb
2.39.2
Michal Suchanek 0f51cb