From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932072AbeENMrQ (ORCPT ); Mon, 14 May 2018 08:47:16 -0400 Received: from terminus.zytor.com ([198.137.202.136]:43583 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752011AbeENMrP (ORCPT ); Mon, 14 May 2018 08:47:15 -0400 Date: Mon, 14 May 2018 05:46:50 -0700 From: tip-bot for Dave Hansen Message-ID: Cc: peterz@infradead.org, linux-kernel@vger.kernel.org, hpa@zytor.com, tglx@linutronix.de, shuah@kernel.org, mingo@kernel.org, dave.hansen@linux.intel.com, linuxram@us.ibm.com, mpe@ellerman.id.au, torvalds@linux-foundation.org, dave.hansen@intel.com Reply-To: mpe@ellerman.id.au, linuxram@us.ibm.com, torvalds@linux-foundation.org, dave.hansen@intel.com, hpa@zytor.com, peterz@infradead.org, linux-kernel@vger.kernel.org, dave.hansen@linux.intel.com, mingo@kernel.org, tglx@linutronix.de, shuah@kernel.org In-Reply-To: <20180509171358.47FD785E@viggo.jf.intel.com> References: <20180509171358.47FD785E@viggo.jf.intel.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/urgent] x86/pkeys: Do not special case protection key 0 Git-Commit-ID: 2fa9d1cfaf0e02f8abef0757002bff12dfcfa4e6 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 2fa9d1cfaf0e02f8abef0757002bff12dfcfa4e6 Gitweb: https://git.kernel.org/tip/2fa9d1cfaf0e02f8abef0757002bff12dfcfa4e6 Author: Dave Hansen AuthorDate: Wed, 9 May 2018 10:13:58 -0700 Committer: Ingo Molnar CommitDate: Mon, 14 May 2018 11:14:45 +0200 x86/pkeys: Do not special case protection key 0 mm_pkey_is_allocated() treats pkey 0 as unallocated. That is inconsistent with the manpages, and also inconsistent with mm->context.pkey_allocation_map. Stop special casing it and only disallow values that are actually bad (< 0). The end-user visible effect of this is that you can now use mprotect_pkey() to set pkey=0. This is a bit nicer than what Ram proposed[1] because it is simpler and removes special-casing for pkey 0. On the other hand, it does allow applications to pkey_free() pkey-0, but that's just a silly thing to do, so we are not going to protect against it. The scenario that could happen is similar to what happens if you free any other pkey that is in use: it might get reallocated later and used to protect some other data. The most likely scenario is that pkey-0 comes back from pkey_alloc(), an access-disable or write-disable bit is set in PKRU for it, and the next stack access will SIGSEGV. It's not horribly different from if you mprotect()'d your stack or heap to be unreadable or unwritable, which is generally very foolish, but also not explicitly prevented by the kernel. 1. http://lkml.kernel.org/r/1522112702-27853-1-git-send-email-linuxram@us.ibm.com Signed-off-by: Dave Hansen Cc: Andrew Morton p Cc: Dave Hansen Cc: Linus Torvalds Cc: Michael Ellermen Cc: Peter Zijlstra Cc: Ram Pai Cc: Shuah Khan Cc: Thomas Gleixner Cc: linux-mm@kvack.org Cc: stable@vger.kernel.org Fixes: 58ab9a088dda ("x86/pkeys: Check against max pkey to avoid overflows") Link: http://lkml.kernel.org/r/20180509171358.47FD785E@viggo.jf.intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mmu_context.h | 2 +- arch/x86/include/asm/pkeys.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 57e3785d0d26..cf9911b5a53c 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -193,7 +193,7 @@ static inline int init_new_context(struct task_struct *tsk, #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { - /* pkey 0 is the default and always allocated */ + /* pkey 0 is the default and allocated implicitly */ mm->context.pkey_allocation_map = 0x1; /* -1 means unallocated or invalid */ mm->context.execute_only_pkey = -1; diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index 39cd292805a9..851c04b7a092 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h @@ -51,10 +51,10 @@ bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) { /* * "Allocated" pkeys are those that have been returned - * from pkey_alloc(). pkey 0 is special, and never - * returned from pkey_alloc(). + * from pkey_alloc() or pkey 0 which is allocated + * implicitly when the mm is created. */ - if (pkey <= 0) + if (pkey < 0) return false; if (pkey >= arch_max_pkey()) return false;