Received: by 10.223.164.202 with SMTP id h10csp355629wrb; Fri, 17 Nov 2017 01:38:28 -0800 (PST) X-Google-Smtp-Source: AGs4zMYa9K0T4CkxkgJxsc65PWymeJzCbregGb17xQngROpkDKF+vy48lvcsL6zjXmfGk/DIBzxK X-Received: by 10.99.108.7 with SMTP id h7mr4471339pgc.343.1510911507897; Fri, 17 Nov 2017 01:38:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510911507; cv=none; d=google.com; s=arc-20160816; b=U0IK97xUQ/CVMBF7I8CJ9WcAzuUz5IxpcIEanpAXJVcXei1QTlIJ/AmwtVwVzfWxph oZFDTTWOrgvtfhbSfHaCt9GDANQ3/sLmOIt7J9BJsl8TKZXqWU8tVzu2Aifx0iyQDOXA 7hE9nCc8y6uEEZVYRNn3waEP6i6VM8xP8cumZsXfTh5bl6+Xh65s91T5bxkbiVn73UAb mbqA/pTqgvxGk4Jy1omatxelihCEVRgFDYXMmNuOLnrQ38GkKqdDte80sr5QwIwBhg7w /b8YCdE18NEcr3HiZZR23AwTfuqRUlzIp4SiJOaOV6TKz5AWzVAjJzksyem98JEeI2pT V07w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature:dkim-signature :arc-authentication-results; bh=whIs8EPhCj3FyGKeZW5s2Bk9Iwb5sJxtTfeFmwcDCx4=; b=DIuwdc6zSGeEnXUR/IEwxnu00BqRUaCfEZWlG7/l1ScjnodiDTix//KJkJQqHF06Q/ iiteHOPR+0qGCoJBnhNZGZkLUSi59nzAci99PRBxeyxmcZXJuLpTdxywwjvXWrdYuO7m AzvbD66A+K9+Asr2QFq7duduQzbyz4+psq4zqtMS0gHBXh+xYWSR/GbqWfhPZ1BOzmQm a0EJnOr9zw7Hl8ZtJZ7i30/LNJ0HNyI2EJXLUnHNG1BsHCLR1pMmq7ZviFcC3TByYRGz KQMBBIBbzCyqiuVM52aAxQLX/k6msT7WkAxz/9uuKiiyxhVFN+3hzuAlN4zQx6/Try39 4hxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=cStW6vZe; dkim=fail header.i=@chromium.org header.s=google header.b=IwoI63H4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o1si2488231pld.44.2017.11.17.01.38.14; Fri, 17 Nov 2017 01:38:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=cStW6vZe; dkim=fail header.i=@chromium.org header.s=google header.b=IwoI63H4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753963AbdKQAaU (ORCPT + 92 others); Thu, 16 Nov 2017 19:30:20 -0500 Received: from mail-io0-f196.google.com ([209.85.223.196]:39421 "EHLO mail-io0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753929AbdKQAaD (ORCPT ); Thu, 16 Nov 2017 19:30:03 -0500 Received: by mail-io0-f196.google.com with SMTP id x63so7095570ioe.6 for ; Thu, 16 Nov 2017 16:30:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=whIs8EPhCj3FyGKeZW5s2Bk9Iwb5sJxtTfeFmwcDCx4=; b=cStW6vZe/fGZUsNQVCBkpj3GozLVCc8HAcKgMCovnWviPltGlbDA36kM4yZZiGRKRr m1JVH5qKjxNbgmV9RuGEbkCdK/7Rd0CczgUDvFYu3C4hrhLcJ1kFAn/KTuPbSrkOiSZU /2s61s86LR2miA+Hb+Wck+06ewz3uYEKnTxSiSEWVWX8zN8Dq8chGYJCIniXrH5soOHp Xaml4oskaGpSazGeV6/WZ0v4VtSX5Fc2gtfMs/zh3a4tjbDySjSiQxSFn1A26dnNNB7a QSqRcfJYgq2RaBJhzQ0YCbCJVWtv5Qzy6f2jht27/qbcIA/nzJpF/iyue1cYnXew+zre 6tWQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=whIs8EPhCj3FyGKeZW5s2Bk9Iwb5sJxtTfeFmwcDCx4=; b=IwoI63H4mAJ2Is5BHOrYnw59QU1VLumw1YcHyyyjfJQM+ZMzhjg1L+YD+FXoAQuKFB JIylCQMWkWG9JtUWb4N2VgPXNWheLKQt3EziD41n/f4baUTfGivPh/ScNVkDO8djfkKn FJBTpUZpqTOnDuFNVRzeXz9Fn47jcwqB0Zbqg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=whIs8EPhCj3FyGKeZW5s2Bk9Iwb5sJxtTfeFmwcDCx4=; b=sOKSGn6e9/GhU2QEwdja5Va0xmbSf4Bviea5PVGgpYVLceA3Xv9qfrKk8uM4QVOMYD SsfbumIV6cz3FRvnIlh76mai/I41CeaMWozmWXBuP+rIGEdQJa3J7jRsvJcGHSoOh7sb Weps/NSLIGuRAzWxhK0aky8QhGZqJlWNir1q+cEOxE1cnkl0EUdTxl2RS/9nPHCegAZJ HgBW3eRM1FfHVOqmAEBEe0muwGAXpElB3m+36lTouXgPyOLZxTDqdEhnYvTfkA++kAju 8eXPsTzDBzYfMkqFyg47TWUi1Yre9nz//TEAEqWRuvqj4yDblW6TJ80hM3NcmfyMOxdc LLoA== X-Gm-Message-State: AJaThX4nWP8i8ine//AG4vpH5PbtONg1DXliWOIOTT4pVL7YgD/7WV/u Qzg8Uy4zu9MrXUJ4tJZ+kN1WWWtCPKn/r1M4f6xSNA== X-Received: by 10.107.53.42 with SMTP id c42mr888214ioa.254.1510878602120; Thu, 16 Nov 2017 16:30:02 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.13.5 with HTTP; Thu, 16 Nov 2017 16:30:01 -0800 (PST) In-Reply-To: <20171116101900.13621-3-mhocko@kernel.org> References: <20171116101900.13621-1-mhocko@kernel.org> <20171116101900.13621-3-mhocko@kernel.org> From: Kees Cook Date: Thu, 16 Nov 2017 16:30:01 -0800 X-Google-Sender-Auth: YlfxtDk0hZNYfo296us3pfIg0Zk Message-ID: Subject: Re: [PATCH 2/2] fs, elf: drop MAP_FIXED usage from elf_map To: Michal Hocko Cc: Linux API , Khalid Aziz , Michael Ellerman , Andrew Morton , Russell King - ARM Linux , Andrea Arcangeli , Linux-MM , LKML , linux-arch , Michal Hocko , Abdul Haleem , Joel Stanley Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Nov 16, 2017 at 2:19 AM, Michal Hocko wrote: > From: Michal Hocko > > Both load_elf_interp and load_elf_binary rely on elf_map to map segments > on a controlled address and they use MAP_FIXED to enforce that. This is > however dangerous thing prone to silent data corruption which can be > even exploitable. Let's take CVE-2017-1000253 as an example. At the time > (before eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE")) > ELF_ET_DYN_BASE was at TASK_SIZE / 3 * 2 which is not that far away from > the stack top on 32b (legacy) memory layout (only 1GB away). Therefore > we could end up mapping over the existing stack with some luck. > > The issue has been fixed since then (a87938b2e246 ("fs/binfmt_elf.c: > fix bug in loading of PIE binaries")), ELF_ET_DYN_BASE moved moved much > further from the stack (eab09532d400 and later by c715b72c1ba4 ("mm: > revert x86_64 and arm64 ELF_ET_DYN_BASE base changes")) and excessive > stack consumption early during execve fully stopped by da029c11e6b1 > ("exec: Limit arg stack to at most 75% of _STK_LIM"). So we should be > safe and any attack should be impractical. On the other hand this is > just too subtle assumption so it can break quite easily and hard to > spot. > > I believe that the MAP_FIXED usage in load_elf_binary (et. al) is still > fundamentally dangerous. Moreover it shouldn't be even needed. We are > at the early process stage and so there shouldn't be unrelated mappings > (except for stack and loader) existing so mmap for a given address > should succeed even without MAP_FIXED. Something is terribly wrong if > this is not the case and we should rather fail than silently corrupt the > underlying mapping. > > Address this issue by changing MAP_FIXED to the newly added > MAP_FIXED_SAFE. This will mean that mmap will fail if there is an > existing mapping clashing with the requested one without clobbering it. > > Cc: Abdul Haleem > Cc: Joel Stanley > Cc: Kees Cook > Signed-off-by: Michal Hocko Once (if?) the name gets settled, this looks good to me: Acked-by: Kees Cook -Kees > --- > arch/metag/kernel/process.c | 6 +++++- > fs/binfmt_elf.c | 12 ++++++++---- > 2 files changed, 13 insertions(+), 5 deletions(-) > > diff --git a/arch/metag/kernel/process.c b/arch/metag/kernel/process.c > index c4606ce743d2..2286140e54e0 100644 > --- a/arch/metag/kernel/process.c > +++ b/arch/metag/kernel/process.c > @@ -398,7 +398,7 @@ unsigned long __metag_elf_map(struct file *filep, unsigned long addr, > tcm_tag = tcm_lookup_tag(addr); > > if (tcm_tag != TCM_INVALID_TAG) > - type &= ~MAP_FIXED; > + type &= ~(MAP_FIXED | MAP_FIXED_SAFE); > > /* > * total_size is the size of the ELF (interpreter) image. > @@ -416,6 +416,10 @@ unsigned long __metag_elf_map(struct file *filep, unsigned long addr, > } else > map_addr = vm_mmap(filep, addr, size, prot, type, off); > > + if ((type & MAP_FIXED_SAFE) && BAD_ADDR(map_addr)) > + pr_info("%d (%s): Uhuuh, elf segement at %p requested but the memory is mapped already\n", > + task_pid_nr(current), tsk->comm, (void*)addr); > + > if (!BAD_ADDR(map_addr) && tcm_tag != TCM_INVALID_TAG) { > struct tcm_allocation *tcm; > unsigned long tcm_addr; > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > index 6466153f2bf0..12b21942ccde 100644 > --- a/fs/binfmt_elf.c > +++ b/fs/binfmt_elf.c > @@ -372,6 +372,10 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, > } else > map_addr = vm_mmap(filep, addr, size, prot, type, off); > > + if ((type & MAP_FIXED_SAFE) && BAD_ADDR(map_addr)) > + pr_info("%d (%s): Uhuuh, elf segement at %p requested but the memory is mapped already\n", > + task_pid_nr(current), current->comm, (void*)addr); > + > return(map_addr); > } > > @@ -569,7 +573,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, > elf_prot |= PROT_EXEC; > vaddr = eppnt->p_vaddr; > if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) > - elf_type |= MAP_FIXED; > + elf_type |= MAP_FIXED_SAFE; > else if (no_base && interp_elf_ex->e_type == ET_DYN) > load_addr = -vaddr; > > @@ -929,7 +933,7 @@ static int load_elf_binary(struct linux_binprm *bprm) > * the ET_DYN load_addr calculations, proceed normally. > */ > if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) { > - elf_flags |= MAP_FIXED; > + elf_flags |= MAP_FIXED_SAFE; > } else if (loc->elf_ex.e_type == ET_DYN) { > /* > * This logic is run once for the first LOAD Program > @@ -965,7 +969,7 @@ static int load_elf_binary(struct linux_binprm *bprm) > load_bias = ELF_ET_DYN_BASE; > if (current->flags & PF_RANDOMIZE) > load_bias += arch_mmap_rnd(); > - elf_flags |= MAP_FIXED; > + elf_flags |= MAP_FIXED_SAFE; > } else > load_bias = 0; > > @@ -1220,7 +1224,7 @@ static int load_elf_library(struct file *file) > (eppnt->p_filesz + > ELF_PAGEOFFSET(eppnt->p_vaddr)), > PROT_READ | PROT_WRITE | PROT_EXEC, > - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, > + MAP_FIXED_SAFE | MAP_PRIVATE | MAP_DENYWRITE, > (eppnt->p_offset - > ELF_PAGEOFFSET(eppnt->p_vaddr))); > if (error != ELF_PAGESTART(eppnt->p_vaddr)) > -- > 2.15.0 > -- Kees Cook Pixel Security From 1584222617397004653@xxx Thu Nov 16 11:40:21 +0000 2017 X-GM-THRID: 1584222617397004653 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread