From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753970AbbIPRuC (ORCPT ); Wed, 16 Sep 2015 13:50:02 -0400 Received: from mga02.intel.com ([134.134.136.20]:30488 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753752AbbIPRtN (ORCPT ); Wed, 16 Sep 2015 13:49:13 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,540,1437462000"; d="scan'208";a="791065177" Subject: [PATCH 24/26] [HIJACKPROT] x86, pkeys: mask off pkeys bits in mprotect() To: dave@sr71.net Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org From: Dave Hansen Date: Wed, 16 Sep 2015 10:49:12 -0700 References: <20150916174903.E112E464@viggo.jf.intel.com> In-Reply-To: <20150916174903.E112E464@viggo.jf.intel.com> Message-Id: <20150916174912.18B301D4@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is a quick hack that puts very x86-specific bits in to mprotect.c. I will fix this up properly if we decide to go forward with the PROT_* scheme for the user ABI for setting up protection keys. --- b/arch/x86/include/uapi/asm/mman.h | 9 +++++---- b/mm/mprotect.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff -puN arch/x86/include/uapi/asm/mman.h~pkeys-82-mprotect-flag-copy arch/x86/include/uapi/asm/mman.h --- a/arch/x86/include/uapi/asm/mman.h~pkeys-82-mprotect-flag-copy 2015-09-16 09:45:54.977451221 -0700 +++ b/arch/x86/include/uapi/asm/mman.h 2015-09-16 09:45:54.982451448 -0700 @@ -24,10 +24,11 @@ ((vm_flags) & VM_PKEY_BIT3 ? _PAGE_PKEY_BIT3 : 0)) #define arch_calc_vm_prot_bits(prot) ( \ - ((prot) & PROT_PKEY0 ? VM_PKEY_BIT0 : 0) | \ - ((prot) & PROT_PKEY1 ? VM_PKEY_BIT1 : 0) | \ - ((prot) & PROT_PKEY2 ? VM_PKEY_BIT2 : 0) | \ - ((prot) & PROT_PKEY3 ? VM_PKEY_BIT3 : 0)) + (!boot_cpu_has(X86_FEATURE_OSPKE) ? 0 : \ + ((prot) & PROT_PKEY0 ? VM_PKEY_BIT0 : 0) | \ + ((prot) & PROT_PKEY1 ? VM_PKEY_BIT1 : 0) | \ + ((prot) & PROT_PKEY2 ? VM_PKEY_BIT2 : 0) | \ + ((prot) & PROT_PKEY3 ? VM_PKEY_BIT3 : 0))) #ifndef arch_validate_prot /* diff -puN mm/mprotect.c~pkeys-82-mprotect-flag-copy mm/mprotect.c --- a/mm/mprotect.c~pkeys-82-mprotect-flag-copy 2015-09-16 09:45:54.978451266 -0700 +++ b/mm/mprotect.c 2015-09-16 09:45:54.982451448 -0700 @@ -344,6 +344,15 @@ fail: return error; } +static unsigned long vm_flags_unaffected_by_mprotect(unsigned long vm_flags) +{ + unsigned long mask_off = VM_READ | VM_WRITE | VM_EXEC; +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + mask_off |= VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | VM_PKEY_BIT3; +#endif + return vm_flags & ~mask_off; +} + SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, unsigned long, prot) { @@ -407,8 +416,10 @@ SYSCALL_DEFINE3(mprotect, unsigned long, /* Here we know that vma->vm_start <= nstart < vma->vm_end. */ + /* Set the vm_flags from the PROT_* bits passed to mprotect */ newflags = vm_flags; - newflags |= (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC)); + /* Copy over all other VMA flags unaffected by mprotect */ + newflags |= vm_flags_unaffected_by_mprotect(vma->vm_flags); /* newflags >> 4 shift VM_MAY% in place of VM_% */ if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) { _