Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp686987imm; Wed, 29 Aug 2018 09:37:34 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaLBjvSPnbkHTbtTlbIznZe0lKQOefvHXRh2xU7P2FqMOMdVi5Y6VL61z4DDI1DoOJ4WJer X-Received: by 2002:a62:f909:: with SMTP id o9-v6mr6713855pfh.141.1535560654762; Wed, 29 Aug 2018 09:37:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535560654; cv=none; d=google.com; s=arc-20160816; b=b4NybqkOxXkoDSKEY6XZavu5mtavQlrxLz81nDOozjT8ihYELaSrRqjLSNn0h2Fxvz hEIspYISLUybM3KL3RMsfUQSHRmHA2OCnp4R/hdsW2u6baRg8xG06lYcY35f2VcuJHtV 0y1hFX4bRreRo+2ycekvL04oouFoPk9/Z3iDQNOeBM6pj74KtsUG37oSmM0Tz1fvGoYH fakJfpGPf9JLmGNhdthRP96YVolYxBAFQPGldsWYg0b8VpL+9GzmoDxYlbvwGcTxmnXn LLa/v/Yp3jDdGMFh1LT79AO2aqfyd+8G/+44OLUW/bnGNKTd6bQK0OVCC/w1cyqk/500 Lumw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:arc-authentication-results; bh=AATwka5Cba4FiY5ejBaSDKKxHArYIKq3r7gT8/UZ480=; b=yUaWEIN5xhqvB37OVZod0p8FGIQS/etjOW2ltGW395QCu//Ba+osTlegROHI4lJau2 GuP9YGm09UoJaAysPTcyvj3dvnY8n+T9aHoxV0p4Jp3rmsAKbJ+IJjtFHi6NKBB8p6S6 r0Zqe63ieOxLEZ3XWqQkAUHrKBsIgxIaQELPHpgr9v05W+mT5bnx8byRj39X/pRgs37Y kRmxr7LUj1DheaRs1R6BrerLfzuw0xtIJNEZ6XrmLyiBFC12uQqllcD5qZV4iVLRU7tQ QMrk1QGGTSpWz+19sgi+MbK2CY6VDrSiPEJbOiVpOsRfe5AhwVfT5gmmpmiM3VnKTaVa M0Lg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=vmware.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u7-v6si4206881plz.353.2018.08.29.09.37.18; Wed, 29 Aug 2018 09:37:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=vmware.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728086AbeH2Udj (ORCPT + 99 others); Wed, 29 Aug 2018 16:33:39 -0400 Received: from ex13-edg-ou-001.vmware.com ([208.91.0.189]:58610 "EHLO EX13-EDG-OU-001.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727245AbeH2Udj (ORCPT ); Wed, 29 Aug 2018 16:33:39 -0400 Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Wed, 29 Aug 2018 09:35:38 -0700 Received: from sc2-haas01-esx0118.eng.vmware.com (sc2-haas01-esx0118.eng.vmware.com [10.172.44.118]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id 73F4DB0795; Wed, 29 Aug 2018 12:35:55 -0400 (EDT) From: Nadav Amit To: Thomas Gleixner CC: Ingo Molnar , , , Nadav Amit , Andi Kleen , Josh Poimboeuf , Michal Hocko , Vlastimil Babka , Dave Hansen , Sean Christopherson , Andy Lutomirski Subject: [RFC PATCH] x86: use WRITE_ONCE() when setting PTEs Date: Wed, 29 Aug 2018 09:34:30 -0700 Message-ID: <20180829163430.207051-1-namit@vmware.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain Received-SPF: None (EX13-EDG-OU-001.vmware.com: namit@vmware.com does not designate permitted sender hosts) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When page-table entries are set, the compiler might optimize their assignment by using multiple instructions to set the PTE. This might turn into a security hazard if the user somehow manages to use the interim PTE. L1TF does not make our lives easier, making even an interim non-present PTE a security hazard. Using WRITE_ONCE() to set PTEs and friends should prevent this potential security hazard. I skimmed the differences in the binary with and without this patch. The differences are (obviously) greater when CONFIG_PARAVIRT=n as more code optimizations are possible. For better and worse, the impact on the binary with this patch is pretty small. Skimming the code did not cause anything to jump out as a security hazard, but it seems that at least move_soft_dirty_pte() caused set_pte_at() to use multiple writes. Cc: Andi Kleen Cc: Thomas Gleixner Cc: Josh Poimboeuf Cc: Michal Hocko Cc: Vlastimil Babka Cc: Dave Hansen Cc: Sean Christopherson Cc: Andy Lutomirski Signed-off-by: Nadav Amit --- arch/x86/include/asm/pgtable_64.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index f773d5e6c8cc..ce2b59047cb8 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -55,15 +55,15 @@ struct mm_struct; void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte); void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte); -static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) +static inline void native_set_pte(pte_t *ptep, pte_t pte) { - *ptep = native_make_pte(0); + WRITE_ONCE(*ptep, pte); } -static inline void native_set_pte(pte_t *ptep, pte_t pte) +static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) { - *ptep = pte; + native_set_pte(ptep, native_make_pte(0)); } static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) @@ -73,7 +73,7 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) { - *pmdp = pmd; + WRITE_ONCE(*pmdp, pmd); } static inline void native_pmd_clear(pmd_t *pmd) @@ -109,7 +109,7 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) static inline void native_set_pud(pud_t *pudp, pud_t pud) { - *pudp = pud; + WRITE_ONCE(*pudp, pud); } static inline void native_pud_clear(pud_t *pud) @@ -137,13 +137,13 @@ static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) pgd_t pgd; if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) { - *p4dp = p4d; + WRITE_ONCE(*p4dp, p4d); return; } pgd = native_make_pgd(native_p4d_val(p4d)); pgd = pti_set_user_pgtbl((pgd_t *)p4dp, pgd); - *p4dp = native_make_p4d(native_pgd_val(pgd)); + WRITE_ONCE(*p4dp, native_make_p4d(native_pgd_val(pgd))); } static inline void native_p4d_clear(p4d_t *p4d) @@ -153,7 +153,7 @@ static inline void native_p4d_clear(p4d_t *p4d) static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd) { - *pgdp = pti_set_user_pgtbl(pgdp, pgd); + WRITE_ONCE(*pgdp, pti_set_user_pgtbl(pgdp, pgd)); } static inline void native_pgd_clear(pgd_t *pgd) -- 2.17.1