From owner-svn-src-all@freebsd.org Fri Oct 18 14:05:14 2019 Return-Path: Delivered-To: svn-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 E19DB151B8B; Fri, 18 Oct 2019 14:05:14 +0000 (UTC) (envelope-from markj@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46vnqG5QKnz4c3K; Fri, 18 Oct 2019 14:05:14 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9A6ACA08C; Fri, 18 Oct 2019 14:05:14 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x9IE5EkL053184; Fri, 18 Oct 2019 14:05:14 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x9IE5EgH053182; Fri, 18 Oct 2019 14:05:14 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201910181405.x9IE5EgH053182@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 18 Oct 2019 14:05:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r353731 - in head/sys: amd64/amd64 conf X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in head/sys: amd64/amd64 conf X-SVN-Commit-Revision: 353731 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Oct 2019 14:05:14 -0000 Author: markj Date: Fri Oct 18 14:05:13 2019 New Revision: 353731 URL: https://svnweb.freebsd.org/changeset/base/353731 Log: Tighten mapping protections on preloaded files on amd64. - We load the kernel at 0x200000. Memory below that address need not be executable, so do not map it as such. - Remove references to .ldata and related sections in the kernel linker script. They come from ld.bfd's default linker script, but are not used, and we now use ld.lld to link the amd64 kernel. lld does not contain a default linker script. - Pad the .bss to a 2MB as we do between .text and .data. This forces the loader to load additional files starting in the following 2MB page, preserving the use of superpage mappings for kernel data. - Map memory above the kernel image with NX. The kernel linker now upgrades protections as needed, and other preloaded file types (e.g., entropy, microcode) need not be mapped with execute permissions in the first place. Reviewed by: kib MFC after: 1 month Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D21859 Modified: head/sys/amd64/amd64/pmap.c head/sys/conf/ldscript.amd64 Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Fri Oct 18 13:56:45 2019 (r353730) +++ head/sys/amd64/amd64/pmap.c Fri Oct 18 14:05:13 2019 (r353731) @@ -1422,22 +1422,22 @@ nkpt_init(vm_paddr_t addr) * * This function operates on 2M pages, since we map the kernel space that * way. - * - * Note that this doesn't currently provide any protection for modules. */ static inline pt_entry_t bootaddr_rwx(vm_paddr_t pa) { /* - * Everything in the same 2M page as the start of the kernel - * should be static. On the other hand, things in the same 2M - * page as the end of the kernel could be read-write/executable, - * as the kernel image is not guaranteed to end on a 2M boundary. + * The kernel is loaded at a 2MB-aligned address, and memory below that + * need not be executable. The .bss section is padded to a 2MB + * boundary, so memory following the kernel need not be executable + * either. Preloaded kernel modules have their mapping permissions + * fixed up by the linker. */ if (pa < trunc_2mpage(btext - KERNBASE) || - pa >= trunc_2mpage(_end - KERNBASE)) - return (X86_PG_RW); + pa >= trunc_2mpage(_end - KERNBASE)) + return (X86_PG_RW | pg_nx); + /* * The linker should ensure that the read-only and read-write * portions don't share the same 2M page, so this shouldn't @@ -1446,6 +1446,7 @@ bootaddr_rwx(vm_paddr_t pa) */ if (pa >= trunc_2mpage(brwsection - KERNBASE)) return (X86_PG_RW | pg_nx); + /* * Mark any 2M page containing kernel text as read-only. Mark * other pages with read-only data as read-only and not executable. Modified: head/sys/conf/ldscript.amd64 ============================================================================== --- head/sys/conf/ldscript.amd64 Fri Oct 18 13:56:45 2019 (r353730) +++ head/sys/conf/ldscript.amd64 Fri Oct 18 14:05:13 2019 (r353731) @@ -45,12 +45,6 @@ SECTIONS .rela.got : { *(.rela.got) } .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.ldata : { *(.rel.ldata .rel.ldata.* .rel.gnu.linkonce.l.*) } - .rela.ldata : { *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) } - .rel.lbss : { *(.rel.lbss .rel.lbss.* .rel.gnu.linkonce.lb.*) } - .rela.lbss : { *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) } - .rel.lrodata : { *(.rel.lrodata .rel.lrodata.* .rel.gnu.linkonce.lr.*) } - .rela.lrodata : { *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } .init : @@ -179,30 +173,10 @@ SECTIONS *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 64 / 8 : 1); + /* Ensure that the .bss section ends at a superpage boundary. + This way it can be mapped using non-executable large pages. */ + . = ALIGN(0x200000); } - .lbss : - { - *(.dynlbss) - *(.lbss .lbss.* .gnu.linkonce.lb.*) - *(LARGE_COMMON) - } - . = ALIGN(64 / 8); - .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.lrodata .lrodata.* .gnu.linkonce.lr.*) - } - .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.ldata .ldata.* .gnu.linkonce.l.*) - . = ALIGN(. != 0 ? 64 / 8 : 1); - } - . = ALIGN(64 / 8); _end = .; PROVIDE (end = .); . = DATA_SEGMENT_END (.); /* Stabs debugging sections. */