Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/aarch64 treat kernel-exec attr and user-exec attr s...
details: https://anonhg.NetBSD.org/src/rev/df500e79ee89
branches: trunk
changeset: 363747:df500e79ee89
user: ryo <ryo%NetBSD.org@localhost>
date: Fri Aug 10 21:06:42 2018 +0000
description:
treat kernel-exec attr and user-exec attr separately.
kernel cannot execute userland exec page, and user cannot execute kernel page.
diffstat:
sys/arch/aarch64/aarch64/locore.S | 6 ++--
sys/arch/aarch64/aarch64/pmap.c | 52 ++++++++++++++++++++++++---------------
sys/arch/aarch64/include/pmap.h | 6 ++--
3 files changed, 38 insertions(+), 26 deletions(-)
diffs (215 lines):
diff -r 001b8c6e9833 -r df500e79ee89 sys/arch/aarch64/aarch64/locore.S
--- a/sys/arch/aarch64/aarch64/locore.S Fri Aug 10 20:35:52 2018 +0000
+++ b/sys/arch/aarch64/aarch64/locore.S Fri Aug 10 21:06:42 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.17 2018/08/10 17:46:06 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.18 2018/08/10 21:06:42 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -35,7 +35,7 @@
#include <aarch64/hypervisor.h>
#include "assym.h"
-RCSID("$NetBSD: locore.S,v 1.17 2018/08/10 17:46:06 maxv Exp $")
+RCSID("$NetBSD: locore.S,v 1.18 2018/08/10 21:06:42 ryo Exp $")
/* #define DEBUG_LOCORE */
/* #define DEBUG_MMU */
@@ -640,7 +640,7 @@
adr x2, start /* physical addr. before MMU */
and x2, x2, #L2_BLK_OA /* L2 block size aligned (2MB) */
mov x1, #VM_MIN_KERNEL_ADDRESS
- mov x3, #L2_BLKPAG_ATTR_NORMAL_WB
+ mov x3, #(L2_BLKPAG_ATTR_NORMAL_WB|LX_BLKPAG_UXN)
/* kernelsize = _end - start */
ldr x1, =start
diff -r 001b8c6e9833 -r df500e79ee89 sys/arch/aarch64/aarch64/pmap.c
--- a/sys/arch/aarch64/aarch64/pmap.c Fri Aug 10 20:35:52 2018 +0000
+++ b/sys/arch/aarch64/aarch64/pmap.c Fri Aug 10 21:06:42 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.17 2018/08/06 12:50:56 ryo Exp $ */
+/* $NetBSD: pmap.c,v 1.18 2018/08/10 21:06:42 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.17 2018/08/06 12:50:56 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.18 2018/08/10 21:06:42 ryo Exp $");
#include "opt_arm_debug.h"
#include "opt_ddb.h"
@@ -163,7 +163,7 @@
};
static pt_entry_t *_pmap_pte_lookup(struct pmap *, vaddr_t);
-static pt_entry_t _pmap_pte_adjust_prot(pt_entry_t, vm_prot_t, vm_prot_t);
+static pt_entry_t _pmap_pte_adjust_prot(pt_entry_t, vm_prot_t, vm_prot_t, bool);
static pt_entry_t _pmap_pte_adjust_cacheflags(pt_entry_t, u_int);
static void _pmap_remove(struct pmap *, vaddr_t, bool);
static int _pmap_enter(struct pmap *, vaddr_t, paddr_t, vm_prot_t, u_int, bool);
@@ -249,11 +249,15 @@
oldpte = l2[l2pde_index(va)];
KDASSERT(!l2pde_valid(oldpte));
- attr = _pmap_pte_adjust_prot(L2_BLOCK, prot, VM_PROT_ALL);
+ attr = _pmap_pte_adjust_prot(L2_BLOCK, prot, VM_PROT_ALL, false);
attr = _pmap_pte_adjust_cacheflags(attr, flags | PMAP_DEV);
#ifdef MULTIPROCESSOR
attr |= LX_BLKPAG_SH_IS;
#endif
+ /* user cannot execute, and kernel follows the prot */
+ attr |= (LX_BLKPAG_UXN|LX_BLKPAG_PXN);
+ if (prot & VM_PROT_EXECUTE)
+ attr &= ~LX_BLKPAG_PXN;
resid = (size + (L2_SIZE - 1)) & ~(L2_SIZE - 1);
size = resid;
@@ -780,9 +784,11 @@
}
static pt_entry_t
-_pmap_pte_adjust_prot(pt_entry_t pte, vm_prot_t prot, vm_prot_t protmask)
+_pmap_pte_adjust_prot(pt_entry_t pte, vm_prot_t prot, vm_prot_t protmask,
+ bool user)
{
vm_prot_t masked;
+ pt_entry_t xn;
masked = prot & protmask;
pte &= ~(LX_BLKPAG_OS_RWMASK|LX_BLKPAG_AF|LX_BLKPAG_AP);
@@ -820,10 +826,12 @@
break;
}
- if ((prot & VM_PROT_EXECUTE) == 0)
- pte |= (LX_BLKPAG_UXN|LX_BLKPAG_PXN);
- else
- pte &= ~(LX_BLKPAG_UXN|LX_BLKPAG_PXN);
+ /* executable for kernel or user? first set never exec both */
+ pte |= (LX_BLKPAG_UXN|LX_BLKPAG_PXN);
+ /* and either to executable */
+ xn = user ? LX_BLKPAG_UXN : LX_BLKPAG_PXN;
+ if (prot & VM_PROT_EXECUTE)
+ pte &= ~xn;
return pte;
}
@@ -1052,6 +1060,7 @@
pt_entry_t *ptep, pte;
vm_prot_t pteprot;
uint32_t mdattr;
+ const bool user = (pv->pv_pmap != pmap_kernel());
UVMHIST_FUNC(__func__);
UVMHIST_CALLED(pmaphist);
@@ -1073,11 +1082,11 @@
pteprot |= VM_PROT_READ;
if ((pte & LX_BLKPAG_AP) == LX_BLKPAG_AP_RW)
pteprot |= VM_PROT_WRITE;
- if ((pte & (LX_BLKPAG_UXN|LX_BLKPAG_PXN)) == 0)
+ if (l3pte_executable(pte, user))
pteprot |= VM_PROT_EXECUTE;
/* new prot = prot & pteprot & mdattr */
- pte = _pmap_pte_adjust_prot(pte, prot & pteprot, mdattr);
+ pte = _pmap_pte_adjust_prot(pte, prot & pteprot, mdattr, user);
atomic_swap_64(ptep, pte);
#if 0
@@ -1093,6 +1102,7 @@
pmap_protect(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
{
vaddr_t va;
+ const bool user = (pm != pmap_kernel());
KASSERT((prot & VM_PROT_READ) || !(prot & VM_PROT_WRITE));
@@ -1159,8 +1169,8 @@
#ifdef UVMHIST
opte = pte;
#endif
- executable = l3pte_executable(pte);
- pte = _pmap_pte_adjust_prot(pte, prot, mdattr);
+ executable = l3pte_executable(pte, user);
+ pte = _pmap_pte_adjust_prot(pte, prot, mdattr, user);
if (!executable && (prot & VM_PROT_EXECUTE)) {
/* non-exec -> exec */
@@ -1419,7 +1429,7 @@
#ifdef UVMHIST
opte = pte;
#endif
- executable = l3pte_executable(pte);
+ executable = l3pte_executable(pte, user);
if (l3pte_valid(pte)) {
KASSERT(!kenter); /* pmap_kenter_pa() cannot override */
@@ -1486,7 +1496,7 @@
}
#endif
- attr = _pmap_pte_adjust_prot(L3_PAGE, prot, mdattr);
+ attr = _pmap_pte_adjust_prot(L3_PAGE, prot, mdattr, user);
attr = _pmap_pte_adjust_cacheflags(attr, flags);
if (VM_MAXUSER_ADDRESS > va)
attr |= LX_BLKPAG_APUSER;
@@ -1780,7 +1790,7 @@
pmap_prot = (VM_PROT_READ|VM_PROT_WRITE);
break;
}
- if ((pte & (LX_BLKPAG_UXN|LX_BLKPAG_PXN)) == 0)
+ if (l3pte_executable(pte, pm != pmap_kernel()))
pmap_prot |= VM_PROT_EXECUTE;
UVMHIST_LOG(pmaphist, "va=%016lx, pmapprot=%08x, accessprot=%08x",
@@ -2063,10 +2073,10 @@
}
if ((prot & VM_PROT_EXECUTE) == 0) {
- pte |= (LX_BLKPAG_UXN|LX_BLKPAG_PXN);
+ pte |= LX_BLKPAG_PXN;
} else {
pte |= LX_BLKPAG_AF;
- pte &= ~(LX_BLKPAG_UXN|LX_BLKPAG_PXN);
+ pte &= ~LX_BLKPAG_PXN;
}
*ptep = pte;
@@ -2152,8 +2162,10 @@
pr(", pmap_read");
if (pte & LX_BLKPAG_OS_WRITE)
pr(", pmap_write");
- if ((pte & (LX_BLKPAG_UXN|LX_BLKPAG_PXN)) == 0)
- pr(", executable");
+ if ((pte & LX_BLKPAG_UXN) == 0)
+ pr(", user-executable");
+ if ((pte & LX_BLKPAG_PXN) == 0)
+ pr(", kernel-executable");
} else {
/* L1 and L2 pde */
diff -r 001b8c6e9833 -r df500e79ee89 sys/arch/aarch64/include/pmap.h
--- a/sys/arch/aarch64/include/pmap.h Fri Aug 10 20:35:52 2018 +0000
+++ b/sys/arch/aarch64/include/pmap.h Fri Aug 10 21:06:42 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.7 2018/08/06 12:50:56 ryo Exp $ */
+/* $NetBSD: pmap.h,v 1.8 2018/08/10 21:06:42 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -95,8 +95,8 @@
#define l2pde_is_table(pde) (((pde) & LX_TYPE) == LX_TYPE_TBL)
#define l3pte_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
-#define l3pte_executable(pde) \
- (((pde) & (LX_BLKPAG_UXN|LX_BLKPAG_PXN)) != (LX_BLKPAG_UXN|LX_BLKPAG_PXN))
+#define l3pte_executable(pde,user) \
+ (((pde) & ((user) ? LX_BLKPAG_UXN : LX_BLKPAG_PXN)) == 0)
#define l3pte_readable(pde) ((pde) & LX_BLKPAG_AF)
#define l3pte_writable(pde) \
(((pde) & (LX_BLKPAG_AF|LX_BLKPAG_AP)) == (LX_BLKPAG_AF|LX_BLKPAG_AP_RW))
Home |
Main Index |
Thread Index |
Old Index