From owner-freebsd-hackers@FreeBSD.ORG Fri Jun 27 07:02:39 2014 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 14EF5500; Fri, 27 Jun 2014 07:02:39 +0000 (UTC) Received: from mail-oa0-x22c.google.com (mail-oa0-x22c.google.com [IPv6:2607:f8b0:4003:c02::22c]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B4D9F2A08; Fri, 27 Jun 2014 07:02:38 +0000 (UTC) Received: by mail-oa0-f44.google.com with SMTP id i7so5215530oag.31 for ; Fri, 27 Jun 2014 00:02:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=YRQbkHS8haCq8pyxu/oSnnYvL2a7OC4z2wz6poa9y6k=; b=z88mDOmvhulogMIP0Y4/PFRlM7ld7N2G1HcH3KCIHJbumXqC9OcP10ay17WQdPzVfa 3I5pr1kHJBcc1fGAdVPeKELXfzffxWbuq6XTCeI5TJ3hAxAbCEB2AFD8hoErOoIa+uaO BUChxtTNRMCA1ytClblboUMrkvWxBh+uszWDwiH6Zqb0yfOGh7m4qemxVi4mtgI92B3u r5CYLShX7H85kAC/2icjHmQ7kCQrlLUxXqaQr8wx8XmF9UTShOwe2yXiRMpSYLTzhg0p TCR80jby+9xRNJZZKEwdDxiXe8QCVNpcWVOl8BGDG4kGest2hpiQBnXrcHHXMoraZV08 Om6Q== MIME-Version: 1.0 X-Received: by 10.60.120.98 with SMTP id lb2mr21059837oeb.52.1403852557948; Fri, 27 Jun 2014 00:02:37 -0700 (PDT) Received: by 10.182.216.197 with HTTP; Fri, 27 Jun 2014 00:02:37 -0700 (PDT) In-Reply-To: <53ACE5B4.8070700@rice.edu> References: <20140626232727.GB1825@pwnie.vrt.sourcefire.com> <53ACE5B4.8070700@rice.edu> Date: Fri, 27 Jun 2014 09:02:37 +0200 Message-ID: Subject: Re: Help With ASLR From: Oliver Pinter To: Alan Cox Content-Type: text/plain; charset=ISO-8859-1 Cc: pageexec@freemail.hu, freebsd-hackers@freebsd.org, kib@freebsd.org, Shawn Webb X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Jun 2014 07:02:39 -0000 On 6/27/14, Alan Cox wrote: > On 06/26/2014 18:27, Shawn Webb wrote: >> Hey All, >> >> I've exchanged a few helpful emails with kib@. He has glanced over the >> ASLR patch we have against 11-CURRENT (which is also attached to this >> email as a reference point). He has suggested some changes to the VM >> subsystem that I'm having trouble getting my head wrapped around. >> >> Essentially, he suggests that instead of doing the randomization in >> various places like the ELF loader and sys_mmap, we should modify >> vm_map_find() in sys/vm/vm_map.c to apply the randomization there. >> >> Here's his suggestion in full (I hope he doesn't mind me directly >> quoting him): >> >> The mapping address randomization can only be performed in the >> vm_map_find(). This is the place where usermode mapping flags are >> already parsed, and the real decision for the placement is done, with >> all the contextual information collected, the fixed requests are not >> passed there. Doing the 'randomization' in vm_mmap() means that the >> mmap command must be parsed twice, which presented patch fails to do >> in any sane way. Only mappings in the usermode maps should be >> randomized. >> >> Current patch does not randomize the mapping location at all, it only >> randomizes the hint address passed from the userspace, which is >> completely useless. > > Kostik, I'm not sure that I understand what you're saying here. The > randomly generated offset is added to the variable "addr" after this > block of code has been executed: > > } else { > /* > * XXX for non-fixed mappings where no hint is provided or > * the hint would fall in the potential heap space, > * place it after the end of the largest possible heap. > * > * There should really be a pmap call to determine a > reasonable > * location. > */ > PROC_LOCK(td->td_proc); > if (addr == 0 || > (addr >= round_page((vm_offset_t)vms->vm_taddr) && > addr < round_page((vm_offset_t)vms->vm_daddr + > lim_max(td->td_proc, RLIMIT_DATA)))) > addr = round_page((vm_offset_t)vms->vm_daddr + > lim_max(td->td_proc, RLIMIT_DATA)); > PROC_UNLOCK(td->td_proc); > } > > So, the point at which the eventual call to vm_map_findspace() starts > looking for free space is determined by the randomization, and thus the > chosen address will be influenced by the randomization. The first > mmap() that I do in one execution of the program will be unlikely to > have the same address in the next execution. > > That said, I think that this block of code would be a better place for > the pax_aslr_mmap() call than were it currently resides. Moving it here > would address the problem with MAP_32BIT mentioned below. > > >> ... It also fails to correct the address to honour >> the placement flags like MAP_32BIT or MAP_ALIGNMENT_MASK. > > > I think that MAP_32BIT is broken, but not MAP_ALIGNMENT_MASK. Whatever > address the patch causes to be passed into vm_map_find(), we will round > it up as necessary to achieve the requested alignment. > > In some sense, the real effect of the map alignment directives, > including automatic alignment for superpages, is going to be to chop off > address bits that Shawn has worked to randomize. More on this below. > See [*]. > >> ... What must >> be done is vm_map_find() requesting vm_map_findspace() for the address >> hole of the size of the requested mapping + (number of address bits to >> randomize << PAGE_SHIFT). Then, the rng value should be obtained and >> final location for the mapping calculated as return value + (rng << >> PAGE_SHIFT). > > > This seems to be trying to implement a different and more complex scheme > than what Shawn is trying to implement. Specifically, suppose that we > have a program that creates 5 mappings with mmap(2). Call them M1, M2, > M3, M4, and M5, respectively. Shawn is perfectly happy for M1 to always > come before M2 in the address space, M2 to always come before M3, and so > on. He's not trying to permute their order in the address space from > one execution of the program to the next. He's only trying to change > their addresses from one execution to the next. The impression that I > got during the BSDCan presentation was that this is what other operating > systems were doing, and it was considered strike a reasonable balance > between run-time overhead and the security benefits. > > >> >> If no address space hole exists which can satisfy the enlarged >> request, either a direct fallback to the initial length should be >> performed (I prefer this), or exponential decrease of the length up to >> the initial size done, and findspace procedure repeated. >> >> Also, the vm_map_find() knows about the superpages hint for the >> mapping being performed, which allows to not break superpages. When >> superpage-aligned mapping is requested, SUPERPAGE_SHIFT (available >> from pagesizes[1]) should be used instead of PAGE_SHIFT in the formula >> above, and probably, a different amount of address bits in the page >> table page level 2 to randomize, selected. > > > [*] I agree with this last observation. I mentioned this possibility > to Shawn after his talk. On machines where pagesizes[1] is defined, > i.e., non-zero, it makes little sense to randomize the low-order address > bits that will be "rounded away" by aligning to pagesizes[1] boundary. > > >> >> === end of kib@ suggestions === >> >> I have a few concerns, though: >> >> 1) vm_map_find is also used when loading certain bits of data in the >> kernel (like KLDs, for example); >> 2) It's not possible to tell in vm_map_find if we're creating a mapping >> for the stack, the execbase, or any other suitable mmap call. We apply >> ASLR differently based on those three aspects; >> 3) vm_map_find is also used in initializing the VM system upon boot. >> What impacts would this cause? >> >> I would really appreciate any feedback. Thank you in advance for any >> help or guidance. > > Shawn, while I'm here, I'll mention that what you were doing with stacks > in pax_aslr_mmap() seemed odd. Can you explain? Alan, the original design of ASLR are there from PaXTeam: http://pax.grsecurity.net/docs/aslr.txt http://pax.grsecurity.net/docs/randmmap.txt > > >