From mboxrd@z Thu Jan 1 00:00:00 1970 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 E493BC54EE9 for ; Thu, 22 Sep 2022 16:47:54 +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-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YwD6YqufD3/a/1imSFpinFJu7iDsg5oUeUiI1dkBBtM=; b=uIJuqPhIUzK2+Z VdAuEcH2JZlCXHLirL04eO3xpyDJwdAut6E8BDD9fNRoXE15iVXFHI8+qDYLOTY+Ru+458Xu47XUg w25dUc88WnPNyHPolFG7NrfOD3bk2t4dJVZh1cyKhCWdzpJwrQvvxDPzGZnG3XSc0AfoV1/tuLanv MQwZaTSB0iKATT2fIZElwjMImOUfEkndm9+VstyhsADAFncX1UOdW5slSv87TP+GSAZSF4DiG1Zlx 3HhetOAMESK7FHbPP4whLsmGrS+y2HBM4rVcOfqEtDHWCxZomJe+ZKPdEWBRd+oeEmgPd08s+f6rV L4KXOJnFMaYHhqCSLjfQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1obPLP-00GscQ-F4; Thu, 22 Sep 2022 16:46:35 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1obPLE-00GsXZ-M0 for linux-arm-kernel@lists.infradead.org; Thu, 22 Sep 2022 16:46:26 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4122316F8; Thu, 22 Sep 2022 09:46:25 -0700 (PDT) Received: from [10.1.196.40] (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 05AF53F5A1; Thu, 22 Sep 2022 09:46:17 -0700 (PDT) Message-ID: <3d62d19b-168c-7b3b-b2a5-1468c1c0bd57@arm.com> Date: Thu, 22 Sep 2022 17:46:13 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: [PATCH] arm64: uaccess: simplify uaccess_mask_ptr() Content-Language: en-GB To: Mark Rutland , linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, james.morse@arm.com, will@kernel.org References: <20220922151053.3520750-1-mark.rutland@arm.com> From: Robin Murphy In-Reply-To: <20220922151053.3520750-1-mark.rutland@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220922_094624_858895_5AB02136 X-CRM114-Status: GOOD ( 33.24 ) 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: , Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On 22/09/2022 4:10 pm, Mark Rutland wrote: > We introduced uaccess pointer masking for arm64 in commit: > > 4d8efc2d5ee4c9cc ("arm64: Use pointer masking to limit uaccess speculation") > > Which was intended to prevent speculative uaccesses to kernel memory on > CPUs where access permissions were not respected under speculation. > > At the time, the uaccess primitives were occasionally used to access > kernel memory, with the maximum permitted address held in > thread_info::addr_limit. Consequently, the address masking needed to > take this dynamic limit into account. > > Subsequently the uaccess primitives were reworked such that they are > only used for user memory, and as of commit: > > 3d2403fd10a1dbb3 ("arm64: uaccess: remove set_fs()") > > ... the address limit was made a compile-time constant, but the logic > was otherwise unchanged. > > Regardless of the configured VA size or whether TBI is in use, the > address space can be divided into three ranges: > > * The TTBR0 VA range, for which any valid pointer has bit 55 *clear*, > and any non-tag bits [63-56] must match bit 55 (i.e. must be clear). > > * The TTBR1 VA range, for which any valid pointer has bit 55 *set*, and > any non-tag bits [63-56] must match bit 55 (i.e. must be set). > > * The gap between the TTBR0 and TTBR1 ranges, where bit 55 may be set or > clear, but any access will result in a fault. > > As the uaccess primitives are now only used for user memory in the TTBR0 > VA range, we can prevent generation of TTBR1 addresses by clearing bit > 55, which will either result in a TTBR0 address or a faulting address > between the TTBR VA ranges. > > This is beneficial for code generation as: > > * We no longer clobber the condition codes. > > * We no longer burn a register on (TASK_SIZE_MAX - 1). > > * We no longer need to consume the untagged pointer. > > When building a defconfig v6.0-rc3 with GCC 12.1.0, this change makes > the resulting Image 64KiB smaller. I have a vague feeling that there was some thought behind sanitising to specifically NULL - otherwise even the original patch could have used a single AND rather than the BICS/CSEL - but it was probably just the overwhelming uncertainty of everything at that time, wherein we could at least reason that maximising the chance of forcing malicious speculation into a fault seemed safest. By now, though, I'm a bit more confident in agreeing that any non-kernel address seems OK for uaccess context. Reviewed-by: Robin Murphy > Signed-off-by: Mark Rutland > Cc: Catalin Marinas > Cc: James Morse > Cc: Robin Murphy > Cc: Will Deacon > --- > arch/arm64/include/asm/uaccess.h | 19 ++++++++++--------- > 1 file changed, 10 insertions(+), 9 deletions(-) > > diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h > index 2fc9f0861769a..e69559826cb8c 100644 > --- a/arch/arm64/include/asm/uaccess.h > +++ b/arch/arm64/include/asm/uaccess.h > @@ -203,9 +203,11 @@ static inline void uaccess_enable_privileged(void) > } > > /* > - * Sanitise a uaccess pointer such that it becomes NULL if above the maximum > - * user address. In case the pointer is tagged (has the top byte set), untag > - * the pointer before checking. > + * Sanitize a uaccess pointer such that it cannot reach any kernel address. > + * > + * Clearing bit 55 ensures the pointer cannot address any portion of the TTBR1 > + * address range (i.e. any kernel address), and either the pointer falls within > + * the TTBR0 address range or must cause a fault. > */ > #define uaccess_mask_ptr(ptr) (__typeof__(ptr))__uaccess_mask_ptr(ptr) > static inline void __user *__uaccess_mask_ptr(const void __user *ptr) > @@ -213,12 +215,11 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr) > void __user *safe_ptr; > > asm volatile( > - " bics xzr, %3, %2\n" > - " csel %0, %1, xzr, eq\n" > - : "=&r" (safe_ptr) > - : "r" (ptr), "r" (TASK_SIZE_MAX - 1), > - "r" (untagged_addr(ptr)) > - : "cc"); > + " bic %0, %1, %2\n" > + : "=r" (safe_ptr) > + : "r" (ptr), > + "i" (BIT(55)) > + ); > > csdb(); > return safe_ptr; _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel