Date: Fri, 27 Jun 2014 09:02:37 +0200 From: Oliver Pinter <oliver.pntr@gmail.com> To: Alan Cox <alc@rice.edu> Cc: pageexec@freemail.hu, freebsd-hackers@freebsd.org, kib@freebsd.org, Shawn Webb <lattera@gmail.com> Subject: Re: Help With ASLR Message-ID: <CAPjTQNEsQGDHdApx0-=h63QN4o=zXKen0Y_6Ehj9_isfgac9tw@mail.gmail.com> In-Reply-To: <53ACE5B4.8070700@rice.edu> References: <20140626232727.GB1825@pwnie.vrt.sourcefire.com> <53ACE5B4.8070700@rice.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On 6/27/14, Alan Cox <alc@rice.edu> 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 > > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPjTQNEsQGDHdApx0-=h63QN4o=zXKen0Y_6Ehj9_isfgac9tw>