From patchwork Thu Nov 27 08:42:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jungseung Lee X-Patchwork-Id: 5393211 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 844919F319 for ; Thu, 27 Nov 2014 08:44:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 89C38201B4 for ; Thu, 27 Nov 2014 08:44:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A55902015E for ; Thu, 27 Nov 2014 08:44:25 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Xtuev-0001Ka-Nf; Thu, 27 Nov 2014 08:42:41 +0000 Received: from mail-pa0-x233.google.com ([2607:f8b0:400e:c03::233]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Xtuet-0001Fw-5j for linux-arm-kernel@lists.infradead.org; Thu, 27 Nov 2014 08:42:39 +0000 Received: by mail-pa0-f51.google.com with SMTP id ey11so4646761pad.10 for ; Thu, 27 Nov 2014 00:42:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=mTPG/KY+yrOWQveTYK/Ia7zVB5OFPbh+6hLlPGguLyo=; b=lznWxR+Yd3ILPInNzUglMs+bnkXpDEaqWEsj9mfGP55EpNiZk0ePeMcadVIyClBi07 5YwxPNcsVnQDl78KsEx3N88iCDdRFG1nWSZdgD0TDpZraenm28uksGQUyVBnEVby6Mt4 a9xpgMcSjD7vsZsZtntOqF0VjE5SvEnYRTXyqYXW0F+2qdKDHg5x0Lqt96EaqpKu4Upn MLLZOoRMnqJUX7v+mXf/06qEtpMtjBjnYwPdECnErHOwn53m5r14/AFE6wFKGY0Q9Jme 9rfFCgNdPfRiaKHU9KYUPhulAZZX7EqeByEwhi6XH6Z29SfyQtkLfzMx3CLz9CRLRJuU Wnqg== X-Received: by 10.70.103.74 with SMTP id fu10mr61024382pdb.53.1417077735652; Thu, 27 Nov 2014 00:42:15 -0800 (PST) Received: from localhost.localdomain ([165.132.120.48]) by mx.google.com with ESMTPSA id fn7sm6466447pad.38.2014.11.27.00.42.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Nov 2014 00:42:14 -0800 (PST) From: Jungseung Lee To: "linux-arm-kernel@lists.infradead.org" , Russell King - ARM Linux , Laura Abbott , Will Deacon , Ard Biesheuvel , Catalin Marinas , Arnd Bergmann Subject: [PATCH v4] arm: Support for the PXN CPU feature on ARMv7 Date: Thu, 27 Nov 2014 17:42:04 +0900 Message-Id: <1417077724-15885-1-git-send-email-js07.lee@gmail.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141127_004239_281502_D9F6967A X-CRM114-Status: GOOD ( 18.09 ) X-Spam-Score: -0.8 (/) Cc: Jungseung Lee X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Modern ARMv7-A/R cores optionally implement below new hardware feature: - PXN: Privileged execute-never(PXN) is a security feature. PXN bit determines whether the processor can execute software from the region. This is effective solution against ret2usr attack. On an implementation that does not include the LPAE, PXN is optionally supported. This patch set PXN bit on user page table for preventing user code execution with privilege mode. Signed-off-by: Jungseung Lee Reviewed-by: Catalin Marinas --- arch/arm/include/asm/pgalloc.h | 10 +++++++++- arch/arm/include/asm/pgtable-2level-hwdef.h | 2 ++ arch/arm/include/asm/pgtable-3level-hwdef.h | 1 + arch/arm/mm/mmu.c | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 78a7793..19cfab5 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -157,7 +157,15 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) { - __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); + extern pmdval_t user_pmd_table; + pmdval_t prot; + + if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE)) + prot = user_pmd_table; + else + prot = _PAGE_USER_TABLE; + + __pmd_populate(pmdp, page_to_phys(ptep), prot); } #define pmd_pgtable(pmd) pmd_page(pmd) diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h index 5cfba15..5e68278 100644 --- a/arch/arm/include/asm/pgtable-2level-hwdef.h +++ b/arch/arm/include/asm/pgtable-2level-hwdef.h @@ -20,12 +20,14 @@ #define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) #define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0) #define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0) +#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */ #define PMD_BIT4 (_AT(pmdval_t, 1) << 4) #define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5) #define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */ /* * - section */ +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */ #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) #define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */ diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h index 9fd61c7..f8f1cff 100644 --- a/arch/arm/include/asm/pgtable-3level-hwdef.h +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h @@ -76,6 +76,7 @@ #define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ +#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */ #define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ /* diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9f98cec..f991c54 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -52,6 +52,8 @@ EXPORT_SYMBOL(empty_zero_page); */ pmd_t *top_pmd; +pmdval_t user_pmd_table = _PAGE_USER_TABLE; + #define CPOLICY_UNCACHED 0 #define CPOLICY_BUFFERED 1 #define CPOLICY_WRITETHROUGH 2 @@ -537,6 +539,14 @@ static void __init build_mem_type_table(void) if (cpu_arch == CPU_ARCH_ARMv6) vecs_pgprot |= L_PTE_MT_VECTORS; #endif + /* + * Check is it with support for the PXN bit + * in the Short-descriptor translation table format descriptors. + */ + if (cpu_arch == CPU_ARCH_ARMv7 && + (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) == 4) { + user_pmd_table |= PMD_PXNTABLE; + } /* * ARMv6 and above have extended page tables. @@ -605,6 +615,11 @@ static void __init build_mem_type_table(void) } kern_pgprot |= PTE_EXT_AF; vecs_pgprot |= PTE_EXT_AF; + + /* + * Set PXN for user mappings + */ + user_pgprot |= PTE_EXT_PXN; #endif for (i = 0; i < 16; i++) {