From patchwork Tue Jan 19 18:31:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 43197 X-Patchwork-Delegate: apw@canonical.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id C9BD6B7CE8 for ; Wed, 20 Jan 2010 05:31:47 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1NXIrZ-0005ih-PL; Tue, 19 Jan 2010 18:31:37 +0000 Received: from smtp.outflux.net ([198.145.64.163]) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1NXIrX-0005iH-Rv for kernel-team@lists.ubuntu.com; Tue, 19 Jan 2010 18:31:36 +0000 Received: from www.outflux.net (serenity-end.outflux.net [10.2.0.2]) by vinyl.outflux.net (8.14.3/8.14.3/Debian-9ubuntu1) with ESMTP id o0JIVYhY000785 for ; Tue, 19 Jan 2010 10:31:34 -0800 Date: Tue, 19 Jan 2010 10:31:34 -0800 From: Kees Cook To: kernel-team@lists.ubuntu.com Subject: [PATCH] UBUNTU: SAUCE: x86: brk away from exec rand area Message-ID: <20100119183134.GP5185@outflux.net> MIME-Version: 1.0 Content-Disposition: inline Organization: Ubuntu X-MIMEDefang-Filter: outflux$Revision: 1.316 $ X-HELO: www.outflux.net X-Scanned-By: MIMEDefang 2.67 on 10.2.0.1 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com This is a fix for the NX emulation patch to force the brk area well outside of the exec randomization area to avoid future allocation or brk growth collisions. Normally this isn't a problem, except when the text region has been loaded from a PIE binary and the CS limit can't be put just above bss. Additionally, the nx-emulation patch was still randomizing addresses even when randomize_va_space was disabled, which would cause collisions even faster if someone tried to disable randomization. BugLink: http://bugs.launchpad.net/bugs/452175 Signed-off-by: Kees Cook Acked-by: Andy Whitcroft Acked-by: Stefan Bader --- arch/x86/kernel/process.c | 12 +++++++++++- mm/mmap.c | 11 ++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 5284cd2..bf5c156 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -607,6 +607,16 @@ unsigned long arch_align_stack(unsigned long sp) unsigned long arch_randomize_brk(struct mm_struct *mm) { unsigned long range_end = mm->brk + 0x02000000; - return randomize_range(mm->brk, range_end, 0) ? : mm->brk; + unsigned long bump = 0; +#ifdef CONFIG_X86_32 + /* in the case of NX emulation, shove the brk segment way out of the + way of the exec randomization area, since it can collide with + future allocations if not. */ + if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) && + (mm->brk < 0x08000000) ) { + bump = (TASK_SIZE/6); + } +#endif + return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk); } diff --git a/mm/mmap.c b/mm/mmap.c index a1483c5..c6d7e53 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1500,8 +1500,11 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0, if (flags & MAP_FIXED) return addr; - if (!addr) - addr = randomize_range(SHLIB_BASE, 0x01000000, len); + if (!addr) { + addr = SHLIB_BASE; + if ((current->flags & PF_RANDOMIZE) && randomize_va_space) + addr = randomize_range(addr, 0x01000000, len); + } if (addr) { addr = PAGE_ALIGN(addr); @@ -1529,7 +1532,9 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0, * Up until the brk area we randomize addresses * as much as possible: */ - if (addr >= 0x01000000) { + if ((current->flags & PF_RANDOMIZE) && + randomize_va_space && + addr >= 0x01000000) { tmp = randomize_range(0x01000000, PAGE_ALIGN(max(mm->start_brk, (unsigned long)0x08000000)), len);