From owner-dev-commits-src-all@freebsd.org Wed Sep 29 16:55:42 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id ACB8E677610; Wed, 29 Sep 2021 16:55:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HKMvL4FWxz4WN0; Wed, 29 Sep 2021 16:55:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6DE861C003; Wed, 29 Sep 2021 16:55:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18TGtggG055219; Wed, 29 Sep 2021 16:55:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18TGtgkk055218; Wed, 29 Sep 2021 16:55:42 GMT (envelope-from git) Date: Wed, 29 Sep 2021 16:55:42 GMT Message-Id: <202109291655.18TGtgkk055218@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: f6de51d3e031 - main - Add the arm64 table attributes and use them MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f6de51d3e0315891f6ea9d12340b98336df409b7 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Sep 2021 16:55:42 -0000 The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=f6de51d3e0315891f6ea9d12340b98336df409b7 commit f6de51d3e0315891f6ea9d12340b98336df409b7 Author: Andrew Turner AuthorDate: 2021-09-23 15:00:55 +0000 Commit: Andrew Turner CommitDate: 2021-09-29 16:53:41 +0000 Add the arm64 table attributes and use them Add the table page table attributes on arm64 and use them to add restrictions to the block and page entries below them. This ensures we are unable to increase the permissions in these last level entries without also changing them in the upper levels. Use the attributes to ensure the kernel can't execute from userspace memory and vice versa, userspace has no access to read or write kernel memory, and that the DMAP region is non-executable. Reviewed by: alc, kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32081 --- sys/arm64/arm64/locore.S | 1 + sys/arm64/arm64/pmap.c | 25 +++++++++++++++++++------ sys/arm64/include/pte.h | 9 +++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index dcc370326671..92415aab1555 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -552,6 +552,7 @@ LENTRY(link_l0_pagetable) /* Build the L0 block entry */ mov x12, #L0_TABLE + orr x12, x12, #(TATTR_UXN_TABLE | TATTR_AP_TABLE_NO_EL0) /* Only use the output address bits */ lsr x9, x9, #PAGE_SHIFT diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index e8a04ee3f2c3..95cb848df14d 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -789,7 +789,8 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa, freemempos += PAGE_SIZE; pmap_store(&pagetable_dmap[l1_slot], - (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE); + (l2_pa & ~Ln_TABLE_MASK) | + TATTR_PXN_TABLE | L1_TABLE); memset(l2, 0, PAGE_SIZE); } @@ -1873,14 +1874,26 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) */ if (ptepindex >= (NUL2E + NUL1E)) { - pd_entry_t *l0; + pd_entry_t *l0p, l0e; vm_pindex_t l0index; l0index = ptepindex - (NUL2E + NUL1E); - l0 = &pmap->pm_l0[l0index]; - KASSERT((pmap_load(l0) & ATTR_DESCR_VALID) == 0, - ("%s: L0 entry %#lx is valid", __func__, pmap_load(l0))); - pmap_store(l0, VM_PAGE_TO_PHYS(m) | L0_TABLE); + l0p = &pmap->pm_l0[l0index]; + KASSERT((pmap_load(l0p) & ATTR_DESCR_VALID) == 0, + ("%s: L0 entry %#lx is valid", __func__, pmap_load(l0p))); + l0e = VM_PAGE_TO_PHYS(m) | L0_TABLE; + + /* + * Mark all kernel memory as not accessible from userspace + * and userspace memory as not executable from the kernel. + * This has been done for the bootstrap L0 entries in + * locore.S. + */ + if (pmap == kernel_pmap) + l0e |= TATTR_UXN_TABLE | TATTR_AP_TABLE_NO_EL0; + else + l0e |= TATTR_PXN_TABLE; + pmap_store(l0p, l0e); } else if (ptepindex >= NUL2E) { vm_pindex_t l0index, l1index; pd_entry_t *l0, *l1; diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h index b3bec720e9f9..6b816464c167 100644 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -38,6 +38,15 @@ typedef uint64_t pd_entry_t; /* page directory entry */ typedef uint64_t pt_entry_t; /* page table entry */ #endif +/* Table attributes */ +#define TATTR_MASK UINT64_C(0xfff8000000000000) +#define TATTR_AP_TABLE_MASK (3UL << 61) +#define TATTR_AP_TABLE_RO (2UL << 61) +#define TATTR_AP_TABLE_NO_EL0 (1UL << 61) +#define TATTR_UXN_TABLE (1UL << 60) +#define TATTR_PXN_TABLE (1UL << 59) +/* Bits 58:51 are ignored */ + /* Block and Page attributes */ #define ATTR_MASK_H UINT64_C(0xfffc000000000000) #define ATTR_MASK_L UINT64_C(0x0000000000000fff)