From patchwork Fri Nov 11 17:11:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 13040621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 839D3C4332F for ; Fri, 11 Nov 2022 17:13:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=v+K65KAzCX220KAge2Y8HRBzefsgilEJZqNruflGe2c=; b=NOW76y4J4Or3bL oTHFrW9Zq5R2w49ewwZrW8X+8pdX61/MPnMclg30WqX4TOCN9RsGPhhdN5AYGeNtUctWFkfPCmqjB ocTO/uMH3mrGDVOzd6dRAtmoRU/exyy5N+wUszoClr44vQub742vw8oaMMg5GP4yW8W136o+VJK58 As2Ysddsukb57YqJYhSr+wLZfBM6CkruBtQVUqlzulIBxSrdCsIRWJfVP2ahMrY/10+Mi7NmP15sU 8FrzLb7OCmzTmCkU7vTGSx0kkJFCO4KP1j2Fa+w1Le7R9nq5OhClXacMKi/h1pcIK/GL9F7/1GNLB WMlz9NaXX8+XyF+B5nVg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otXa2-00H7c9-WD; Fri, 11 Nov 2022 17:12:39 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otXZl-00H7RY-8F for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 17:12:23 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CB9B6B8266E; Fri, 11 Nov 2022 17:12:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 984F8C433C1; Fri, 11 Nov 2022 17:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1668186738; bh=qzKbwL9KoW2qdSFtBE3vjEm/r9f60lnL1qosf/Uto1M=; h=From:To:Cc:Subject:Date:From; b=BiqMeNs5qupl87rhxTT26iD0YD3Q0U4t7Cv3u+sLrWR0T9ETYWdf9v46V/2+9rLaM BZVhRiImsrm5Ea9R2MnxEUvEkiOcF9wmoAuW1fVDGq3VJpVPB7l/8lI1v/cF4aunaV cWtikMt8Luau7mSehPA2K7evlX1MfjwqZqx5PRY0PWUfve+9oA5EOa2tYFSbZlFW3d qH/sSmt+D+E31DpzIJz5Z847HxsMqvIbYYtpeRKHDzSGhfk3fi741xhUwF9xIUW/Tu NGDkGJzNMMz8A513dli8cdskPplo3Hfc+37aqt63uq4Cncq4av4NVf0sEnnDdTdlpd XGXPz3YlThNVA== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Marc Zyngier , Will Deacon , Mark Rutland , Kees Cook , Catalin Marinas , Mark Brown , Anshuman Khandual Subject: [PATCH v7 00/33] arm64: robustify boot sequence and add support for WXN Date: Fri, 11 Nov 2022 18:11:28 +0100 Message-Id: <20221111171201.2088501-1-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9013; i=ardb@kernel.org; h=from:subject; bh=qzKbwL9KoW2qdSFtBE3vjEm/r9f60lnL1qosf/Uto1M=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjboIoOpsc4mxCdCQ3cEWLL2iKv0z1wQgkdXk2yeFG qMkmZTWJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY26CKAAKCRDDTyI5ktmPJIDSC/ 4jzPuWFKJTSpttrfDvkme/xDbA5ETVhtwerjgOSP16muIP9uuAFnsicr6ZJa1XWMv1i4SRzy3vUqb4 /ZDCeQdvW+QKX2EfDu5I2bU5uxcELgsLAry8VGGEocvivphMQEyuMYLVGetFYQAO60FTUefn7WNO5l XEL1xMBcmkIQIcA3dOSLky/lycHnCDfZJQT0l8Wa+y9P/6xTYli1A/HOezox5/6ybI55xxY2Qi7SdM DIqwmvCiVQPJMl6fhCTm2xuynPxMYEg3MWBQQFTEGi3CQumz4usKT0M1ahs6e2tLIAdJ3mLbz6TUHU JQUyUaSJjf6FPRyrg04WqShDWCzNmRiFFLe+z0n/vz66TpRtn5V6NJIA+X6oxc/FKmWQfYD6ebySI3 QWH7jvmzQBWXaNb1Q3I+Sxy9JNWbTESg9y/cec4vOL31HQBUrUHp2HvTSFL20WdB7oNEXzziXC25TO jglnnss62+KVLHDUS7evycVx6Fku5LmTi3uRJazfOvau0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_091221_617024_6A502ABE X-CRM114-Status: GOOD ( 37.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The purpose of this series is to make the boot sequence more robust, and more efficient, by trying to adhere to the following principles: - do as little as possible before enabling the MMU and caches [1] - do everything only once - do everything from C code - don't rely on mappings that are executable and writable at the same time [2] - avoid handling external input while the kernel text is mapped writable. [1] has been addressed already with the exception of some EFI specific tweaks that have been sent out separately: https://lore.kernel.org/all/20221108182204.2447664-1-ardb@kernel.org/ [2] this is a useful principle in general, but also a prerequisite for allowing WXN to be enabled, which was the inspiration for this work. The size of the series has ballooned a bit, but I think the first ~8 patches could be picked up piecemeal, while the remainder is being discussed and maybe respun again (or rejected). The bulk of the series covers changes that are needed so that the kernel mapping is created only once, and before it is used to execute the kernel. All C code that implements this and its dependencies is moved into the early mini C runtime that was added recently for the early KASLR init code. The most intrusive changes of the series are the ones that modify the early CPU feature override detection in idreg-override.c. This is needed to get rid of absolute symbol references (which is not trivial in this code, which is highly dependent on statically allocated data structures containing pointers to functions and other global objects). It is also needed to remove the dependency on kernel infrastructure for command line parsing etc. The resulting code can execute from the initial ID map, and populate the feature override variables that have been moved into BSS (which is the only part of the kernel image that is mapped writable in the initial ID map) Also, a new C implementation is provided to create the permanent kernel mapping without the need to pivot through a temporary one based on block mappings. This permanent mapping is created with all the necessary attributes that support the optional features detected (and potentially overridden) beforehand. This means the kernel mapping code in mm/mmu.c can be retired, along with the handling of the switch between the two and the copying of Kasan shadow mappings and fixmap intermediate page table levels. WXN === The final two patches cover the remaining changes that are needed to enable WXN support, which is desirable for robustness, given that writable, executable mappings of memory are too easy to subvert, and in the kernel, we rarely rely on such mappings anyway. Setting SCTLR_ELx.WXN makes all writable mappings implicitly non-executable, and when set at EL1, it affects EL0 as well as EL1. This means we need some diligence on the part of user space, but fortunately, most JITs and other user space components that actually need to manipulate the contents of their own executable code use split views on the same memory, or switch between RW- and R-X and back. (One notable exception is V8, which recently switched back to a full RWX mappings based JIT) So on the user space side, we need a couple of minor tweaks to validate the mmap()/mprotect() arguments when WXN is in effect, and to handle any faults that might occur on such mappings. Changes since v6: - radical overhaul of the boot code to move the feature override detection before the permanent mapping of the kernel is created - rebase onto arm64/dynamic-scs and incorporate the initial dynamic SCS patching into the early C map_kernel() routine as well - remove some false dependences on the SWAPPER_BLOCK_xxx constants, and rename them now that they no longer apply to swapper_pg_dir, but only to the initial ID map (v5 was a subset of v4 without the WXN specific pieces) Changes since v4: [0] - don't move __ro_after_init section now that we no longer need to, - don't complicate the asm kernel mapping routines further, but instead, merge the two existing passes into one implemented in C, - deal with rodata=off on WXN enabled builds (i.e., turn off WXN as well), - add some acks from Kees Cc: Marc Zyngier Cc: Will Deacon Cc: Mark Rutland Cc: Kees Cook Cc: Catalin Marinas Cc: Mark Brown Cc: Anshuman Khandual Ard Biesheuvel (32): arm64: mm: Avoid SWAPPER_BLOCK_xxx constants in FDT fixmap logic arm64: mm: Avoid swapper block size when choosing vmemmap granularity arm64: kaslr: don't pretend KASLR is enabled if offset < MIN_KIMG_ALIGN arm64: kaslr: drop special case for ThunderX in kaslr_requires_kpti() arm64: kernel: Disable latent_entropy GCC plugin in early C runtime arm64: kernel: Add relocation check to code built under pi/ arm64: kernel: Don't rely on objcopy to make code under pi/ __init arm64: head: move relocation handling to C code arm64: idreg-override: Omit non-NULL checks for override pointer arm64: idreg-override: Use relative references to override variables arm64: idreg-override: Use relative references to filter routines arm64: idreg-override: Avoid parameq() and parameqn() arm64: idreg-override: avoid strlen() to check for empty strings arm64: idreg-override: Avoid sprintf() for simple string concatenation arm64: idreg_override: Avoid kstrtou64() to parse a single hex digit arm64: idreg-override: Move to early mini C runtime arm64: kernel: Remove early fdt remap code arm64: head: Clear BSS and the kernel page tables in one go arm64: Move feature overrides into the BSS section arm64: head: Run feature override detection before mapping the kernel arm64: head: move dynamic shadow call stack patching into early C runtime arm64: kaslr: Use feature override instead of parsing the cmdline again arm64: idreg-override: Create a pseudo feature for rodata=off arm64: head: allocate more pages for the kernel mapping arm64: head: move memstart_offset_seed handling to C code arm64: head: Move early kernel mapping routines into C code arm64: mm: avoid fixmap for early swapper_pg_dir updates arm64: mm: omit redundant remap of kernel image arm64: Revert "mm: provide idmap pointer to cpu_replace_ttbr1()" arm64: mmu: Retire SWAPPER_BLOCK_xxx and related constants mm: add arch hook to validate mmap() prot flags arm64: mm: add support for WXN memory translation attribute Marc Zyngier (1): arm64: Turn kaslr_feature_override into a generic SW feature override arch/arm64/Kconfig | 11 + arch/arm64/include/asm/cpufeature.h | 15 + arch/arm64/include/asm/fixmap.h | 5 +- arch/arm64/include/asm/kasan.h | 2 - arch/arm64/include/asm/kernel-pgtable.h | 69 ++-- arch/arm64/include/asm/memory.h | 11 + arch/arm64/include/asm/mman.h | 36 ++ arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/include/asm/mmu_context.h | 43 ++- arch/arm64/include/asm/scs.h | 34 +- arch/arm64/include/asm/setup.h | 3 - arch/arm64/kernel/Makefile | 7 +- arch/arm64/kernel/cpufeature.c | 32 +- arch/arm64/kernel/head.S | 208 ++---------- arch/arm64/kernel/idreg-override.c | 321 ------------------ arch/arm64/kernel/image-vars.h | 28 ++ arch/arm64/kernel/kaslr.c | 10 +- arch/arm64/kernel/module.c | 2 +- arch/arm64/kernel/pi/Makefile | 24 +- arch/arm64/kernel/pi/idreg-override.c | 356 ++++++++++++++++++++ arch/arm64/kernel/pi/kaslr_early.c | 70 +--- arch/arm64/kernel/pi/map_kernel.c | 306 +++++++++++++++++ arch/arm64/kernel/{ => pi}/patch-scs.c | 34 +- arch/arm64/kernel/pi/pi.h | 12 + arch/arm64/kernel/pi/relacheck.c | 104 ++++++ arch/arm64/kernel/pi/relocate.c | 63 ++++ arch/arm64/kernel/setup.c | 22 -- arch/arm64/kernel/suspend.c | 2 +- arch/arm64/kernel/vmlinux.lds.S | 16 +- arch/arm64/mm/kasan_init.c | 19 +- arch/arm64/mm/mmu.c | 160 +++------ arch/arm64/mm/proc.S | 9 +- include/linux/mman.h | 15 + mm/mmap.c | 3 + 34 files changed, 1188 insertions(+), 866 deletions(-) delete mode 100644 arch/arm64/kernel/idreg-override.c create mode 100644 arch/arm64/kernel/pi/idreg-override.c create mode 100644 arch/arm64/kernel/pi/map_kernel.c rename arch/arm64/kernel/{ => pi}/patch-scs.c (90%) create mode 100644 arch/arm64/kernel/pi/pi.h create mode 100644 arch/arm64/kernel/pi/relacheck.c create mode 100644 arch/arm64/kernel/pi/relocate.c