From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-541790-1524851492-2-10009801618868905912 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, HEADER_FROM_DIFFERENT_DOMAINS 0.25, MAILING_LIST_MULTI -1, ME_NOAUTH 0.01, RCVD_IN_DNSWL_HI -5, LANGUAGES en, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='US', FromHeader='com', MailFrom='org' X-Spam-charsets: X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: stable-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=fm2; t= 1524851491; b=DXk4OrMtKVp2K3SuF80zWkkN13DYZxRX0X2BaVHpO/46jldW7N JEQ9sPjmBhYPYcrOIgHcq6WGVQZbnkGHHdB8ms+lpkKB1tEkXj/zKLE69w4j+e9c 3FQz08JYgJXhnd8PbrTj/Foba9G1T+SpOtYOW5FysqtNYvpNUucKtPeDQrvqi/z6 SIJV/L6bRvHLMfIoCNpIiAxQDUMCCENuxF+F2nGsgJJcqsjiIGrI0Z0XsnzMY9BA JU6hn2FG89I5DUFwErAwQHw+ackCugZtXioqqVvVVMNMrXH7Dq0V+sGt+XHgS0Ms iH8MtytdbETsVuH39iAA8pN55oyh9EUC0wsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=subject:to:cc:from:date:references :in-reply-to:message-id:sender:list-id; s=fm2; t=1524851491; bh= 3E0jQ4sFaDFdD1yiENKB8gD+YsgFcmc51jbv1MrgSk4=; b=Ic02j0gegG+3iznM sCvuTrROFTRD5q4YKX3k641COVpwfTQNiGybFoMXUrnhMB7TK3P7ZzBuHQBvql3I EGI0SWZGL82tPT5qWakMTg5oOg50riZzB4ldrGrVHjiKPJcICBoj8i+0EXbqQzv6 fTsHDV59Zwuhutefj1fp7KAnMkM5RDMwL/ND9NwL4dtKgHnyqcXX+c55WuvXOKve I91KU1nCZwMqe6cn5icDjzCAJnDFs8AqaLsQmImd0G1uGe+VIIRhj6ePAXJU+h1o 9+aDM9Fzue22/JD3/StVlvZyF9mqnq7DgfqWY0mi9QaW1XwXM3W2MrJpmaT3iQdH uVQJwg== ARC-Authentication-Results: i=1; mx5.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=linux.intel.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=stable-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-cm=none score=0; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=linux.intel.com header.result=pass header_org.domain=intel.com header_org.result=pass header_is_org_domain=no; x-vs=clean score=0 state=0 Authentication-Results: mx5.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=linux.intel.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=stable-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-cm=none score=0; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=linux.intel.com header.result=pass header_org.domain=intel.com header_org.result=pass header_is_org_domain=no; x-vs=clean score=0 state=0 X-ME-VSCategory: clean X-CM-Envelope: MS4wfE3ReBs08LuDOwIQ0x9YpcROOfKGzjf4900qnWIdOanjVhEiK0dbkpKXuBvejg14HwInBfEGLtMi+2VR4NpXa9ExWIJz/d9NiMqy/uhE9ZK/hLr9TAVg r6nyaVVrNmrLsb9rXzbK3TWynkV2UrrA2oHf86NlNJDHSEjZQW2wYiiVhDuMTd+PfrTeA8/xHrNzw80f7lbwFTp1UgHJ/U0oL8vTr6qbDD5XfMbg/sS/960g X-CM-Analysis: v=2.3 cv=NPP7BXyg c=1 sm=1 tr=0 a=UK1r566ZdBxH71SXbqIOeA==:117 a=UK1r566ZdBxH71SXbqIOeA==:17 a=Kd1tUaAdevIA:10 a=QyXUC8HyAAAA:8 a=1XWaLZrsAAAA:8 a=VwQbUJbxAAAA:8 a=VnNF1IyMAAAA:8 a=Z4Rwk6OoAAAA:8 a=WexYMCiOe6C4khrCuiUA:9 a=AjGcO6oz07-iQ99wixmX:22 a=HkZW87K1Qel5hWWM3VKY:22 X-ME-CMScore: 0 X-ME-CMCategory: none Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757607AbeD0RvN (ORCPT ); Fri, 27 Apr 2018 13:51:13 -0400 Received: from mga17.intel.com ([192.55.52.151]:55914 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757605AbeD0Rtw (ORCPT ); Fri, 27 Apr 2018 13:49:52 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,336,1520924400"; d="scan'208";a="223961119" 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, stable@vger.kernel.org, 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, 27 Apr 2018 10:45:32 -0700 References: <20180427174527.0031016C@viggo.jf.intel.com> In-Reply-To: <20180427174527.0031016C@viggo.jf.intel.com> Message-Id: <20180427174532.B20FFEA3@viggo.jf.intel.com> Sender: stable-owner@vger.kernel.org X-Mailing-List: stable@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: 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. Signed-off-by: Dave Hansen Fixes: 62b5f7d013f ("mm/core, x86/mm/pkeys: Add execute-only protection keys support") Reported-by: Shakeel Butt Cc: stable@vger.kernel.org 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 | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 11 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-04-26 10:42:18.971487371 -0700 +++ b/arch/x86/include/asm/pkeys.h 2018-04-26 10:42:18.977487371 -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-04-26 10:42:18.973487371 -0700 +++ b/arch/x86/mm/pkeys.c 2018-04-26 10:47:34.806486584 -0700 @@ -94,26 +94,27 @@ 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, * fall through as if we do not have execute-only - * support. + * support in this mm. */ if (prot == PROT_EXEC) { 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 _