[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1514480352.431042096@decadent.org.uk>
Date: Thu, 28 Dec 2017 16:59:12 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org,
"Martin Schwidefsky" <schwidefsky@...ibm.com>,
"Gerald Schaefer" <gerald.schaefer@...ibm.com>
Subject: [PATCH 3.2 11/94] s390/mm: fix write access check in gup_huge_pmd()
3.2.97-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Gerald Schaefer <gerald.schaefer@...ibm.com>
commit ba385c0594e723d41790ecfb12c610e6f90c7785 upstream.
The check for the _SEGMENT_ENTRY_PROTECT bit in gup_huge_pmd() is the
wrong way around. It must not be set for write==1, and not be checked for
write==0. Fix this similar to how it was fixed for ptes long time ago in
commit 25591b070336 ("[S390] fix get_user_pages_fast").
One impact of this bug would be unnecessarily using the gup slow path for
write==0 on r/w mappings. A potentially more severe impact would be that
gup_huge_pmd() will succeed for write==1 on r/o mappings.
Signed-off-by: Gerald Schaefer <gerald.schaefer@...ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@...ibm.com>
[bwh: Backported to 3.2:
- Segment flag names are different
- Adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
arch/s390/mm/gup.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -51,13 +51,12 @@ static inline int gup_pte_range(pmd_t *p
static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
- unsigned long mask, result;
struct page *head, *page, *tail;
+ unsigned long mask;
int refs;
- result = write ? 0 : _SEGMENT_ENTRY_RO;
- mask = result | _SEGMENT_ENTRY_INV;
- if ((pmd_val(pmd) & mask) != result)
+ mask = (write ? _SEGMENT_ENTRY_RO : 0) | _SEGMENT_ENTRY_INV;
+ if ((pmd_val(pmd) & mask) != 0)
return 0;
VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT));
Powered by blists - more mailing lists