From patchwork Tue Jun 13 00:10:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Edgecombe, Rick P" X-Patchwork-Id: 13277748 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 995EDC7EE2E for ; Tue, 13 Jun 2023 00:13:30 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3151B8E0022; Mon, 12 Jun 2023 20:12:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2785A8E000B; Mon, 12 Jun 2023 20:12:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 07AF78E0022; Mon, 12 Jun 2023 20:12:40 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id D87268E000B for ; Mon, 12 Jun 2023 20:12:40 -0400 (EDT) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id B008012038F for ; Tue, 13 Jun 2023 00:12:40 +0000 (UTC) X-FDA: 80895798480.15.DD82501 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by imf01.hostedemail.com (Postfix) with ESMTP id 903EA4000B for ; Tue, 13 Jun 2023 00:12:38 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=TuMDuGQ+; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf01.hostedemail.com: domain of rick.p.edgecombe@intel.com designates 134.134.136.65 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1686615158; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=j/S9+lJTj7lOJLdBjMtY21maw2CmhDPCo82KqZj1ygs=; b=Yw6FqlbkqCFg1edhG38t9NhDYkVIVlcQUCjBkE7n4rtXckPFZYS1SerOFDDB5VUzdzfh5O A9As9VeNU4uZL59JqnjxF1ovQZ8FbG0gQo6rImf6TqtEi4yHGXPO9xLo70btTBVDP+npvx s8O/1yytycT87AwL2NKt7rOeZKPMwmo= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=TuMDuGQ+; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf01.hostedemail.com: domain of rick.p.edgecombe@intel.com designates 134.134.136.65 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1686615158; a=rsa-sha256; cv=none; b=SJJXPGGbX8xT2ct9zY/idSGFHy5M8LHRJ/0nwCAvzFBOVXnGDPdGvEqyVxxpfGQAttHR4L CXdgCHrMf0k9BQ7YuNRn6XUCVDIrNFm2hw1UT1PuggOmLgQWSrzw4t8qRUIsiOb9rOV6ZV 3W62JFaMrnsNBhRkqI8fyZ2re8WUj74= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686615158; x=1718151158; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=T7gc3JiJMbmruUv2dTeFaPrm+ED2TBUgFQFH5yJf4mA=; b=TuMDuGQ+bVKbHvVgiXg4Rptm7zpSz/mAAFVTQEHniVOERzkmCtxlOXNx wQjxP3J0blNOFqv/nYvjp6n2HiqHe1QRpq9z2AazPV4zJSd6LaajmSYNY i9uYb/L0fKZEYO01l0z0JYNcXdw/f9q+I3o0wcSCjNjWcvktWwOTkmvGD 22jl5N6e4k+lRfy9C66I/o/zJ8nNYzAfvA1z+Cx2CIHKnA2sCNpS+hKyC bvtGLP4xlAdAOQkyN9tBfoiXUMJs2WtDSi0zfLA/NlwHwP52+lytG4WdR ndTbKiCFOYZSids/h4TtrO6vD4Nid/VqcXkbDOzcfo8PEXczdL610DULM g==; X-IronPort-AV: E=McAfee;i="6600,9927,10739"; a="361557448" X-IronPort-AV: E=Sophos;i="6.00,238,1681196400"; d="scan'208";a="361557448" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jun 2023 17:12:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10739"; a="835671121" X-IronPort-AV: E=Sophos;i="6.00,238,1681196400"; d="scan'208";a="835671121" Received: from almeisch-mobl1.amr.corp.intel.com (HELO rpedgeco-desk4.amr.corp.intel.com) ([10.209.42.242]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jun 2023 17:12:36 -0700 From: Rick Edgecombe To: x86@kernel.org, "H . Peter Anvin" , Thomas Gleixner , Ingo Molnar , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-api@vger.kernel.org, Arnd Bergmann , Andy Lutomirski , Balbir Singh , Borislav Petkov , Cyrill Gorcunov , Dave Hansen , Eugene Syromiatnikov , Florian Weimer , "H . J . Lu" , Jann Horn , Jonathan Corbet , Kees Cook , Mike Kravetz , Nadav Amit , Oleg Nesterov , Pavel Machek , Peter Zijlstra , Randy Dunlap , Weijiang Yang , "Kirill A . Shutemov" , John Allen , kcc@google.com, eranian@google.com, rppt@kernel.org, jamorris@linux.microsoft.com, dethoma@microsoft.com, akpm@linux-foundation.org, Andrew.Cooper3@citrix.com, christina.schimpe@intel.com, david@redhat.com, debug@rivosinc.com, szabolcs.nagy@arm.com, torvalds@linux-foundation.org, broonie@kernel.org Cc: rick.p.edgecombe@intel.com Subject: [PATCH v9 33/42] x86/shstk: Check that signal frame is shadow stack mem Date: Mon, 12 Jun 2023 17:10:59 -0700 Message-Id: <20230613001108.3040476-34-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230613001108.3040476-1-rick.p.edgecombe@intel.com> References: <20230613001108.3040476-1-rick.p.edgecombe@intel.com> MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 903EA4000B X-Stat-Signature: j5xcbqfjawidnqih3ebyuboui43zhzq5 X-Rspam-User: X-HE-Tag: 1686615158-309852 X-HE-Meta: U2FsdGVkX19nhSTCQDbeEUkS4rbAgSIVFVMq3mV+KPrmZcrsQYCHcQG81nErx4wuAl9vMVDCpteMa1gODqEbybUQ7gG1o26vLChbkMwHDErxH1ti6UkNLL+vSp3+aegYahpdSlH/ncSzk6yBqmqVKUTMTIcQJKuvGOR330Q7DIbQyeJZhMBOJaPF7I1sOavsVW9Syrc5JTNf0L8TNL2UBg1k+KI/PwtH2ju+VDVGQscmpt4HNRusJkKpycN9UHuJoWhSMUDHaKyzZV0/Uas9ELdGT0B/G1Rgrsxl+QTJoyKkiiUji+SMlIU0dArMh5NWfMtxXEWwkxMYwm8Wt/6zEOkel2kkI1N7McTJGnURJmLWSP+RywXlwm/UOjZcDreEfy6U6k6B0kB5oTBIRV91UbiOw9KyLQ4QIl0/uIqdALenSLfebtX5qYgsAscOigQhZm+ND45Ts79jB016G8drB8R043ldafRdHhyc9hjU7Ky+3D7Cnq8S5pjxqfoyiNoC6nN8kYMkNfJ8z3Q+IDT3KUB9WAMVa+crQnkCl4Cf3tSD05DOgtxW12r+TOjdLYul3S98Snf2gHgWEwyf4kOxGYHhvCIQU32+IAZ+rfcX7Xo3QVK0q4oAX95bLGpvk28GWrDmYB3lzpKnw3H6RwTtXlEueF3uHHXR4vGENWsPO2pJfV354XgFrOJ76fiLCQhbi1B9eXblzcQH0btJM9jO4vQoJoR9Gf29V3zjKTNaRxWPcNutcrZGzce9VRR9w85W9ZSSag6cxOK9S5IiGltBiVZDMCKqaanEKrhb9qdt3XcWqXJCUN5GOMbMl4nuhNA2W+bRwFf2CiN919Nmotw67iNiFF9Vm2ek7XpOUhNJUK2Brj4PTB3oJB2Auws10TNlOKWd+zWqbYHVXnAhrz2RdpTRbiOF3XfaYawJkJeK8dwJknRuG8JSKeIcG5Y9tNpfQVB2tLCGXztxJhHEJAB 9KZ91rEA EeeXOld5BjpTdI4VfGmgCS4X4QWTRJ9Jx9F/c6rvKmhwpZw1mwT/+XyT8j8YAfyk6RpF670bPLIW3uJIeVc6O/TYXQ2Xtys/5LCumZmQSdv8XLE7qje+Lqk9p5X63j463BZZoxZtsTHAYaj6ic77Lc32u9veh8JCBFDXRA9CclPhJ6vdbYEU3bJBcNEo4vvDNA19TzM4kYFSdPspvGaRkazN4KqWC3uVfM/C/3ceZiKNGEnoBuwKl560bBQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The shadow stack signal frame is read by the kernel on sigreturn. It relies on shadow stack memory protections to prevent forgeries of this signal frame (which included the pre-signal SSP). This behavior helps userspace protect itself. However, using the INCSSP instruction userspace can adjust the SSP to 8 bytes beyond the end of a shadow stack. INCSSP performs shadow stack reads to make sure it doesn’t increment off of the shadow stack, but on the end position it actually reads 8 bytes below the new SSP. For the shadow stack HW operations, this situation (INCSSP off the end of a shadow stack by 8 bytes) would be fine. If the a RET is executed, the push to the shadow stack would fail to write to the shadow stack. If a CALL is executed, the SSP will be incremented back onto the stack and the return address will be written successfully to the very end. That is expected behavior around shadow stack underflow. However, the kernel doesn’t have a way to read shadow stack memory using shadow stack accesses. WRUSS can write to shadow stack memory with a shadow stack access which ensures the access is to shadow stack memory. But unfortunately for this case, there is no equivalent instruction for shadow stack reads. So when reading the shadow stack signal frames, the kernel currently assumes the SSP is pointing to the shadow stack and uses a normal read. The SSP pointing to shadow stack memory will be true in most cases, but as described above, in can be untrue by 8 bytes. So lookup the VMA of the shadow stack sigframe being read to verify it is shadow stack. Since the SSP can only be beyond the shadow stack by 8 bytes, and shadow stack memory is page aligned, this check only needs to be done when this type of relative position to a page boundary is encountered. So skip the extra work otherwise. Signed-off-by: Rick Edgecombe --- v9: - New patch --- arch/x86/kernel/shstk.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c index a8705f7d966c..50733a510446 100644 --- a/arch/x86/kernel/shstk.c +++ b/arch/x86/kernel/shstk.c @@ -249,15 +249,38 @@ static int shstk_push_sigframe(unsigned long *ssp) static int shstk_pop_sigframe(unsigned long *ssp) { + struct vm_area_struct *vma; unsigned long token_addr; - int err; + bool need_to_check_vma; + int err = 1; + /* + * It is possible for the SSP to be off the end of a shadow stack by 4 + * or 8 bytes. If the shadow stack is at the start of a page or 4 bytes + * before it, it might be this case, so check that the address being + * read is actually shadow stack. + */ if (!IS_ALIGNED(*ssp, 8)) return -EINVAL; + need_to_check_vma = PAGE_ALIGN(*ssp) == *ssp; + + if (need_to_check_vma) + mmap_read_lock_killable(current->mm); + err = get_shstk_data(&token_addr, (unsigned long __user *)*ssp); if (unlikely(err)) - return err; + goto out_err; + + if (need_to_check_vma) { + vma = find_vma(current->mm, *ssp); + if (!vma || !(vma->vm_flags & VM_SHADOW_STACK)) { + err = -EFAULT; + goto out_err; + } + + mmap_read_unlock(current->mm); + } /* Restore SSP aligned? */ if (unlikely(!IS_ALIGNED(token_addr, 8))) @@ -270,6 +293,10 @@ static int shstk_pop_sigframe(unsigned long *ssp) *ssp = token_addr; return 0; +out_err: + if (need_to_check_vma) + mmap_read_unlock(current->mm); + return err; } int setup_signal_shadow_stack(struct ksignal *ksig)