From patchwork Tue May 14 13:04:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Austin X-Patchwork-Id: 2570451 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork1.kernel.org (Postfix) with ESMTP id B96733FC5A for ; Wed, 15 May 2013 08:30:26 +0000 (UTC) Received: from merlin.infradead.org ([205.233.59.134]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcFAo-0003ls-9g; Tue, 14 May 2013 13:22:05 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcEvs-0005sS-1s; Tue, 14 May 2013 13:06:20 +0000 Received: from service87.mimecast.com ([91.220.42.44]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcEuz-0005lQ-86 for linux-arm-kernel@lists.infradead.org; Tue, 14 May 2013 13:05:28 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 14 May 2013 14:05:03 +0100 Received: from e102895-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 14 May 2013 14:05:03 +0100 From: Jonathan Austin To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 8/8] ARM: mpu: protect the vectors page with an MPU region Date: Tue, 14 May 2013 14:04:44 +0100 Message-Id: <1368536684-13608-9-git-send-email-jonathan.austin@arm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1368536684-13608-1-git-send-email-jonathan.austin@arm.com> References: <1368536684-13608-1-git-send-email-jonathan.austin@arm.com> X-OriginalArrivalTime: 14 May 2013 13:05:03.0199 (UTC) FILETIME=[A5CE86F0:01CE50A3] X-MC-Unique: 113051414050304001 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130514_090525_656565_D00C9355 X-CRM114-Status: GOOD ( 18.58 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [91.220.42.44 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Jonathan Austin , Nicolas Pitre , Catalin Marinas , will.deacon@arm.com, hyok.choi@samsung.com, u.kleine-koenig@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 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 Without an MMU it is possible for userspace programs to start executing code in places that they have no business executing. The MPU allows some level of protection against this. This patch protects the vectors page from access by userspace processes. Userspace tasks that dereference a null pointer are already protected by an svc at 0x0 that kills them. However when tasks use an offset from a null pointer (eg a function in a null struct) they miss this carefully placed svc and enter the exception vectors in user mode, ending up in the kernel. This patch causes programs that do this to receive a SEGV instead of happily entering the kernel in user-mode, and hence avoid a 'Bad Mode' panic. As part of this change it is necessary to make sigreturn happen via the stack when there is not an sa_restorer function. This change is invisible to userspace, and irrelevant to code compiled using a uClibc toolchain, which always uses an sa_restorer function. Because we don't get to remap the vectors in !MMU kuser_helpers are not in a defined location, and hence aren't usable. This means we don't need to worry about keeping them accessible from PL0 Signed-off-by: Jonathan Austin Reviewed-by: Will Deacon CC: Nicolas Pitre CC: Catalin Marinas --- arch/arm/include/asm/mpu.h | 1 + arch/arm/kernel/head-nommu.S | 16 ++++++++++++++++ arch/arm/kernel/signal.c | 9 +++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/mpu.h b/arch/arm/include/asm/mpu.h index 0014834..c3247cc 100644 --- a/arch/arm/include/asm/mpu.h +++ b/arch/arm/include/asm/mpu.h @@ -46,6 +46,7 @@ #define MPU_PROBE_REGION 0 #define MPU_BG_REGION 1 #define MPU_RAM_REGION 2 +#define MPU_VECTORS_REGION 3 /* Maximum number of regions Linux is interested in */ #define MPU_MAX_REGIONS 16 diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 3d3071b..0640704 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -21,6 +21,7 @@ #include #include #include +#include /* * Kernel startup entry point. @@ -184,6 +185,7 @@ ENDPROC(__after_proc_init) * Region 0: Use this for probing the MPU details, so leave disabled. * Region 1: Background region - covers the whole of RAM as strongly ordered * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6 + * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page * * r6: Value to be written to DRSR (and IRSR if required) for MPU_RAM_REGION */ @@ -228,6 +230,20 @@ ENTRY(__setup_mpu) setup_region r0, r5, r6, MPU_INSTR_SIDE @ 0x0, BG region, enabled 2: isb + /* Vectors region */ + set_region_nr r0, #MPU_VECTORS_REGION + isb + /* Shared, inaccessible to PL0, rw PL1 */ + mov r0, #CONFIG_VECTORS_BASE @ Cover from VECTORS_BASE + ldr r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL) + /* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */ + mov r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) + + setup_region r0, r5, r6, MPU_DATA_SIDE @ VECTORS_BASE, PL0 NA, enabled + beq 3f @ Memory-map not unified + setup_region r0, r5, r6, MPU_INSTR_SIDE @ VECTORS_BASE, PL0 NA, enabled +3: isb + /* Enable the MPU */ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR bic r0, r0, #CR_BR @ Disable the 'default mem-map' diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 296786b..1c16c35 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -392,14 +392,19 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, if (ksig->ka.sa.sa_flags & SA_SIGINFO) idx += 3; + /* + * Put the sigreturn code on the stack no matter which return + * mechanism we use in order to remain ABI compliant + */ if (__put_user(sigreturn_codes[idx], rc) || __put_user(sigreturn_codes[idx+1], rc+1)) return 1; - if (cpsr & MODE32_BIT) { + if ((cpsr & MODE32_BIT) && !IS_ENABLED(CONFIG_ARM_MPU)) { /* * 32-bit code can use the new high-page - * signal return code support. + * signal return code support except when the MPU has + * protected the vectors page from PL0 */ retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; } else {