Received: by 10.213.65.68 with SMTP id h4csp597832imn; Fri, 23 Mar 2018 11:14:23 -0700 (PDT) X-Google-Smtp-Source: AG47ELvpNLj77jJnwBWZ7ohFSUUHA8rW3ECDzXp5FjCc/Gio6ZY3txMWZUk6zK7r1H1TRgTE6c7F X-Received: by 10.101.77.198 with SMTP id q6mr15730393pgt.61.1521828863117; Fri, 23 Mar 2018 11:14:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521828863; cv=none; d=google.com; s=arc-20160816; b=g7/tmU2HmUFBbhC1Xq/6H1+e/Wj0w48nXK737bfNkdBuaGOKSx1mUgCsV7PXD9qP78 DCzD9ILB7Mm4rB59NzqG2uzGIdHgDQMwKl/lbAEvELDA9X919HRiZdCnxzQEqvhICYtT 96ud7dV7/n6MgQEaRxbz497dSZKwWxFF8Odt92Qz5aa5EhDWMBNqdEr/zqlTTkJ33wSr Raqqhhy5uVRZgvInsQGedcbosiXJpEdKZ3dN9XxYY2Kxp+M14tBSAJ0iHUvGvpn62uDL 1kxAUXj82TavQeAp7vHcP4whwk09Dl6SlVznkfuS9vGDPU1JvZspW027kf0+qJkwKVgC Ltfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:in-reply-to:references:date :from:cc:to:subject:arc-authentication-results; bh=euSa4U71Cs/BZwrjU5OhbhUxz6mE5MF0G8dfh0cyfe0=; b=LRCQlvSgNe8ms0yDUx+ouOusgjuA1z0NRjWykKok/j+gYZGvL0bctCy3HSamvcZnDP pyJkmyV8I7YluhxEo9seRZuAmvKHJ1sf5V1aGhhSgBqldQLjaasHDAJaUSoz4LEu4dP7 pP5kMkUJdH9o18TB/QDadqz0bMN2K0Gb3S8bOfINUwvbLABkdLx6vz8z6qrHuWyVjVz8 hmHUQDRzjn9eZDk3qc8apj6yHX2wZsxVsUKsekaa291swv//1iNI33T7PjYcxvakzBiK CJccMBLDkg7PYeFYfZm/UzC5OPxtA8ckFyBOftoPCOi2czXqSvxt16EyU495LRulq1FW 9T6A== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s184si3774589pgb.0.2018.03.23.11.14.07; Fri, 23 Mar 2018 11:14:23 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752618AbeCWSMt (ORCPT + 99 others); Fri, 23 Mar 2018 14:12:49 -0400 Received: from mga01.intel.com ([192.55.52.88]:38106 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752189AbeCWSLM (ORCPT ); Fri, 23 Mar 2018 14:11:12 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Mar 2018 11:11:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,351,1517904000"; d="scan'208";a="214308467" Received: from viggo.jf.intel.com (HELO localhost.localdomain) ([10.54.39.119]) by fmsmga005.fm.intel.com with ESMTP; 23 Mar 2018 11:11:12 -0700 Subject: [PATCH 4/9] x86, pkeys: override pkey when moving away from PROT_EXEC To: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, Dave Hansen , shakeelb@google.com, linuxram@us.ibm.com, tglx@linutronix.de, dave.hansen@intel.com, mpe@ellerman.id.au, mingo@kernel.org, akpm@linux-foundation.org, shuah@kernel.org From: Dave Hansen Date: Fri, 23 Mar 2018 11:09:11 -0700 References: <20180323180903.33B17168@viggo.jf.intel.com> In-Reply-To: <20180323180903.33B17168@viggo.jf.intel.com> Message-Id: <20180323180911.E43ACAB8@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen I got a bug report that the following code (roughly) was causing a SIGSEGV: mprotect(ptr, size, PROT_EXEC); mprotect(ptr, size, PROT_NONE); mprotect(ptr, size, PROT_READ); *ptr = 100; The problem is hit when the mprotect(PROT_EXEC) is implicitly assigned a protection key to the VMA, and made that key ACCESS_DENY|WRITE_DENY. The PROT_NONE mprotect() failed to remove the protection key, and the PROT_NONE-> PROT_READ left the PTE usable, but the pkey still in place and left the memory inaccessible. To fix this, we ensure that we always "override" the pkee at mprotect() if the VMA does not have execute-only permissions, but the VMA has the execute-only pkey. We had a check for PROT_READ/WRITE, but it did not work for PROT_NONE. This entirely removes the PROT_* checks, which ensures that PROT_NONE now works. Reported-by: Shakeel Butt Signed-off-by: Dave Hansen Cc: Ram Pai Cc: Thomas Gleixner Cc: Dave Hansen Cc: Michael Ellermen Cc: Ingo Molnar Cc: Andrew Morton Cc: Shuah Khan --- b/arch/x86/include/asm/pkeys.h | 12 +++++++++++- b/arch/x86/mm/pkeys.c | 19 ++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff -puN arch/x86/include/asm/pkeys.h~pkeys-abandon-exec-only-pkey-more-aggressively arch/x86/include/asm/pkeys.h --- a/arch/x86/include/asm/pkeys.h~pkeys-abandon-exec-only-pkey-more-aggressively 2018-03-21 15:47:49.810198922 -0700 +++ b/arch/x86/include/asm/pkeys.h 2018-03-21 15:47:49.816198922 -0700 @@ -2,6 +2,8 @@ #ifndef _ASM_X86_PKEYS_H #define _ASM_X86_PKEYS_H +#define ARCH_DEFAULT_PKEY 0 + #define arch_max_pkey() (boot_cpu_has(X86_FEATURE_OSPKE) ? 16 : 1) extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, @@ -15,7 +17,7 @@ extern int __execute_only_pkey(struct mm static inline int execute_only_pkey(struct mm_struct *mm) { if (!boot_cpu_has(X86_FEATURE_OSPKE)) - return 0; + return ARCH_DEFAULT_PKEY; return __execute_only_pkey(mm); } @@ -56,6 +58,14 @@ bool mm_pkey_is_allocated(struct mm_stru return false; if (pkey >= arch_max_pkey()) return false; + /* + * The exec-only pkey is set in the allocation map, but + * is not available to any of the user interfaces like + * mprotect_pkey(). + */ + if (pkey == mm->context.execute_only_pkey) + return false; + return mm_pkey_allocation_map(mm) & (1U << pkey); } diff -puN arch/x86/mm/pkeys.c~pkeys-abandon-exec-only-pkey-more-aggressively arch/x86/mm/pkeys.c --- a/arch/x86/mm/pkeys.c~pkeys-abandon-exec-only-pkey-more-aggressively 2018-03-21 15:47:49.812198922 -0700 +++ b/arch/x86/mm/pkeys.c 2018-03-21 15:47:49.816198922 -0700 @@ -94,15 +94,7 @@ int __arch_override_mprotect_pkey(struct */ if (pkey != -1) return pkey; - /* - * Look for a protection-key-drive execute-only mapping - * which is now being given permissions that are not - * execute-only. Move it back to the default pkey. - */ - if (vma_is_pkey_exec_only(vma) && - (prot & (PROT_READ|PROT_WRITE))) { - return 0; - } + /* * The mapping is execute-only. Go try to get the * execute-only protection key. If we fail to do that, @@ -113,7 +105,16 @@ int __arch_override_mprotect_pkey(struct pkey = execute_only_pkey(vma->vm_mm); if (pkey > 0) return pkey; + } else if (vma_is_pkey_exec_only(vma)) { + /* + * Protections are *not* PROT_EXEC, but the mapping + * is using the exec-only pkey. This mapping was + * PROT_EXEC and will no longer be. Move back to + * the default pkey. + */ + return ARCH_DEFAULT_PKEY; } + /* * This is a vanilla, non-pkey mprotect (or we failed to * setup execute-only), inherit the pkey from the VMA we _