From patchwork Sun Mar 19 00:15:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Edgecombe, Rick P" X-Patchwork-Id: 71667 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:604a:0:0:0:0:0 with SMTP id j10csp527536wrt; Sat, 18 Mar 2023 18:18:29 -0700 (PDT) X-Google-Smtp-Source: AK7set+EKpw8T4sQrJBV08+VlVu9Bp2YpbKg6Y4iuwoRLl7tnXmlP0hGeBmWd8Ize63aVrNODWB/ X-Received: by 2002:a05:6a20:1613:b0:d5:a476:b159 with SMTP id l19-20020a056a20161300b000d5a476b159mr15490444pzj.61.1679188709165; Sat, 18 Mar 2023 18:18:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679188709; cv=none; d=google.com; s=arc-20160816; b=WRy/cU5D6wlUvC2J0sELtKsG6PmZvzkJSUM0aiLZAENI66dEwB/jnIHczN43einOxH yPyAFit9cSsMN1wb//auZjQnWuqYQ0P0gmgUE+y3k0WP/TW9CMP1GbetZUn28U+0YP34 N7L24ALEUwjk9ychOCHgojf0Tg4Q0obw4kUEcMj/ecLLz83lWTsPhupEOACw/xqq8cLn tTtjMLsMRHSphZW8nhprUy0ngLyELm3k2yZYQdzGWbetEpT+KsLwhcky+5634lasrY6n jqGrj7Zsui2MLgt7O7yFybkSR1XhHjLh8f6qwWqEmhgrFerUByUYOFJOveHbXdCGDi94 XXEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=QkKdIBSM6+NW96X7S3iu9foVuWMjrTX9oD9LGR3hCIY=; b=ZNzYeNjg7TZwRtoLIojWfWrRalnkB8nUmYEuy9N3HX/GEb7EGZHo+gLh6A/g1SqYoX FIna9+UrOxqGWsMPEORlrQBfDSDPWhJWQiMIBV+Hx+/xE7ThlmfExEOMXF/5AoToe8Hs 3i/RkcwFUJCdBR0z9dezAwM5hj8jovXOdSBCk/KbO4Zenc0FWTlrctKhAQA//dRVGwNY xheN81uK2Ffby3cGZKGAAu/0XcV8+mZndn3+COU60Tkb8tX/Wcq4beZdOPt/n+eQmOVk VEF7iJRKg6vhCS5KBVoiZ48plNifu7lGL1owHV63GaS9teYiXR6KmSFo8Prf/BhKZSMR 5TgA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="PqFoSa7/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q28-20020a635c1c000000b0050b8a7635dfsi6259866pgb.295.2023.03.18.18.18.16; Sat, 18 Mar 2023 18:18:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="PqFoSa7/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229981AbjCSAVS (ORCPT + 99 others); Sat, 18 Mar 2023 20:21:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230110AbjCSAUk (ORCPT ); Sat, 18 Mar 2023 20:20:40 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2E6729164; Sat, 18 Mar 2023 17:19:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679185140; x=1710721140; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=hsI3rH3pI5zk+4z/rTXM9tpk9smi32a1UvWDoOYm7ZQ=; b=PqFoSa7/6Z5cmCTiu11VWoCfxMrMU7vhg/2XObKVjJqnOgzg6jK7DhBE drxJnb8txN/5olsNU5b1HANo7xjSuEn5034CLGrQEjjsvSxS6dY7GbmCu moIpbTw19UQvIjcWwZSHc7zdwS2mjrPQ/0/wxXSn31wvyAbeSbFc1piZt s5+IRz4CCzE1ZHmwyuqrTniDsUgghhm1o49mysE8CxtIgHs1HsXorl7XZ p+zaePi92v1DvIxzlH0iiRIBvY+4rcqHnjRGc1Xk2ZQ7xB1Yvg5ncXUFH pipP52qAgr5KQKiPZ0QXF2Bwgw9Wz3JVDG8r+ERVUkcJMl6x1k0YUoJl3 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10653"; a="338491306" X-IronPort-AV: E=Sophos;i="5.98,272,1673942400"; d="scan'208";a="338491306" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Mar 2023 17:16:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10653"; a="749672895" X-IronPort-AV: E=Sophos;i="5.98,272,1673942400"; d="scan'208";a="749672895" Received: from bmahatwo-mobl1.gar.corp.intel.com (HELO rpedgeco-desk.amr.corp.intel.com) ([10.135.34.5]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Mar 2023 17:16: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 Cc: rick.p.edgecombe@intel.com Subject: [PATCH v8 26/40] mm: Warn on shadow stack memory in wrong vma Date: Sat, 18 Mar 2023 17:15:21 -0700 Message-Id: <20230319001535.23210-27-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230319001535.23210-1-rick.p.edgecombe@intel.com> References: <20230319001535.23210-1-rick.p.edgecombe@intel.com> X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1760756979986015272?= X-GMAIL-MSGID: =?utf-8?q?1760756979986015272?= 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. One sharp edge is that PTEs that are both Write=0 and Dirty=1 are treated as shadow by the CPU, but this combination used to be created by the kernel on x86. Previous patches have changed the kernel to now avoid creating these PTEs unless they are for shadow stack memory. In case any missed corners of the kernel are still creating PTEs like this for non-shadow stack memory, and to catch any re-introductions of the logic, warn if any shadow stack PTEs (Write=0, Dirty=1) are found in non-shadow stack VMAs when they are being zapped. This won't catch transient cases but should have decent coverage. It will be compiled out when shadow stack is not configured. In order to check if a PTE is shadow stack in core mm code, add two arch breakouts arch_check_zapped_pte/pmd(). This will allow shadow stack specific code to be kept in arch/x86. Signed-off-by: Rick Edgecombe Reviewed-by: Kees Cook Acked-by: Mike Rapoport (IBM) Tested-by: Pengfei Xu Tested-by: John Allen Tested-by: Kees Cook Acked-by: David Hildenbrand --- v8: - Update commit log verbaige (Boris) v6: - Add arch breakout to remove shstk from core MM code. v5: - Fix typo in commit log v3: - New patch --- arch/x86/include/asm/pgtable.h | 6 ++++++ arch/x86/mm/pgtable.c | 12 ++++++++++++ include/linux/pgtable.h | 14 ++++++++++++++ mm/huge_memory.c | 1 + mm/memory.c | 1 + 5 files changed, 34 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 2e3d8cca1195..e5b3dce0d9fe 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1684,6 +1684,12 @@ static inline bool arch_has_hw_pte_young(void) return true; } +#define arch_check_zapped_pte arch_check_zapped_pte +void arch_check_zapped_pte(struct vm_area_struct *vma, pte_t pte); + +#define arch_check_zapped_pmd arch_check_zapped_pmd +void arch_check_zapped_pmd(struct vm_area_struct *vma, pmd_t pmd); + #ifdef CONFIG_XEN_PV #define arch_has_hw_nonleaf_pmd_young arch_has_hw_nonleaf_pmd_young static inline bool arch_has_hw_nonleaf_pmd_young(void) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 98856bcc8102..afab0bc7862b 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -906,3 +906,15 @@ pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) return pmd; } + +void arch_check_zapped_pte(struct vm_area_struct *vma, pte_t pte) +{ + VM_WARN_ON_ONCE(!(vma->vm_flags & VM_SHADOW_STACK) && + pte_shstk(pte)); +} + +void arch_check_zapped_pmd(struct vm_area_struct *vma, pmd_t pmd) +{ + VM_WARN_ON_ONCE(!(vma->vm_flags & VM_SHADOW_STACK) && + pmd_shstk(pmd)); +} diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index c63cd44777ec..4a8970b9fb11 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -291,6 +291,20 @@ static inline bool arch_has_hw_pte_young(void) } #endif +#ifndef arch_check_zapped_pte +static inline void arch_check_zapped_pte(struct vm_area_struct *vma, + pte_t pte) +{ +} +#endif + +#ifndef arch_check_zapped_pmd +static inline void arch_check_zapped_pmd(struct vm_area_struct *vma, + pmd_t pmd) +{ +} +#endif + #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index aaf815838144..24797be05fcb 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1689,6 +1689,7 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, */ orig_pmd = pmdp_huge_get_and_clear_full(vma, addr, pmd, tlb->fullmm); + arch_check_zapped_pmd(vma, orig_pmd); tlb_remove_pmd_tlb_entry(tlb, pmd, addr); if (vma_is_special_huge(vma)) { if (arch_needs_pgtable_deposit()) diff --git a/mm/memory.c b/mm/memory.c index d0972d2d6f36..c953c2c4588c 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1389,6 +1389,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, continue; ptent = ptep_get_and_clear_full(mm, addr, pte, tlb->fullmm); + arch_check_zapped_pte(vma, ptent); tlb_remove_tlb_entry(tlb, pte, addr); zap_install_uffd_wp_if_needed(vma, addr, pte, details, ptent);