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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCF5DC433FE for ; Fri, 4 Nov 2022 22:43:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230037AbiKDWnF (ORCPT ); Fri, 4 Nov 2022 18:43:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230298AbiKDWmW (ORCPT ); Fri, 4 Nov 2022 18:42:22 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C2AD51C2C; Fri, 4 Nov 2022 15:39:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1667601587; x=1699137587; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=kPqO2kwM78EGnIAhrKsxSWDtILBo5g6MXomNZ5elCHU=; b=DGAXFOrtwsEH7TIFKWN3+OLNoiH39FOkhIVerZx8QcRLr4gUntxODpvF W1W/HX8GLOlwSZFE8h44wZy47pIiraGN1p1nolxc9up/kmGwQCEv89Mw0 y9hYICJpEn6Dv3qWpRolN42+qHKxJBejnuLnxRqQsSIwWiQVb3h14EaoV rK51yBCuB7AQqIPsnnPUN63tUZwAiTw0y/ld5/UOYYkX0DSrDqWrz+XgW TEKWSxaJdpz6cSnUtIMiaEZJzWtNZM9+XMC5qZ2CvfLVJ4AoXoQk+RNAM XH+mc8xBRs+D79t5EAJnAiUx7M6bLuqrx1MkTPkc7LResKBKXbcVDQv1O Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10521"; a="311840568" X-IronPort-AV: E=Sophos;i="5.96,138,1665471600"; d="scan'208";a="311840568" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Nov 2022 15:39:42 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10521"; a="668514096" X-IronPort-AV: E=Sophos;i="5.96,138,1665471600"; d="scan'208";a="668514096" Received: from adhjerms-mobl1.amr.corp.intel.com (HELO rpedgeco-desk.amr.corp.intel.com) ([10.212.227.68]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Nov 2022 15:39:41 -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 , "Ravi V . Shankar" , 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 Cc: rick.p.edgecombe@intel.com Subject: [PATCH v3 22/37] mm: Don't allow write GUPs to shadow stack memory Date: Fri, 4 Nov 2022 15:35:49 -0700 Message-Id: <20221104223604.29615-23-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221104223604.29615-1-rick.p.edgecombe@intel.com> References: <20221104223604.29615-1-rick.p.edgecombe@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The x86 Control-flow Enforcement Technology (CET) feature includes a new type of memory called shadow stack. This shadow stack memory has some unusual properties, which requires some core mm changes to function properly. Shadow stack memory is writable only in very specific, controlled ways. However, since it is writable, the kernel treats it as such. As a result there remain many ways for userspace to trigger the kernel to write to shadow stack's via get_user_pages(, FOLL_WRITE) operations. To make this a little less exposed, block writable GUPs for shadow stack VMAs. Still allow FOLL_FORCE to write through shadow stack protections, as it does for read-only protections. Tested-by: Pengfei Xu Tested-by: John Allen Signed-off-by: Rick Edgecombe --- v3: - Add comment in __pte_access_permitted() (Dave) - Remove unneeded shadow stack specific check in __pte_access_permitted() (Jann) arch/x86/include/asm/pgtable.h | 5 +++++ mm/gup.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index d57dc1b2d3e8..0d18f3a4373d 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1637,6 +1637,11 @@ static inline bool __pte_access_permitted(unsigned long pteval, bool write) { unsigned long need_pte_bits = _PAGE_PRESENT|_PAGE_USER; + /* + * Write=0,Dirty=1 PTEs are shadow stack, which the kernel + * shouldn't generally allow access to, but since they + * are already Write=0, the below logic covers both cases. + */ if (write) need_pte_bits |= _PAGE_RW; diff --git a/mm/gup.c b/mm/gup.c index fe195d47de74..411befd4d431 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1062,7 +1062,7 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) return -EFAULT; if (write) { - if (!(vm_flags & VM_WRITE)) { + if (!(vm_flags & VM_WRITE) || (vm_flags & VM_SHADOW_STACK)) { if (!(gup_flags & FOLL_FORCE)) return -EFAULT; /* -- 2.17.1