oss-sec mailing list archives

Re: Offset2lib: bypassing full ASLR on 64bit Linux


From: Daniel Micay <danielmicay () gmail com>
Date: Wed, 10 Dec 2014 13:20:05 -0500

On 10/12/14 09:25 AM, Steve Grubb wrote:
On Tuesday, December 09, 2014 10:09:02 PM Steve Grubb wrote:
On Tuesday, December 09, 2014 08:03:10 PM Daniel Micay wrote:
On 09/12/14 11:18 AM, Steve Grubb wrote:
4) Then I started wondering about the heap when you use other memory
manager libraries such as jemalloc. This turned out to be interesting.
You get about 19 bits of randomness using it. Its not as bad as non-PIE
glibc but not as good as PIE glibc. You also got the same amount of
randomness whether the app was PIE or not. This is an area ripe for more
experimenting, exploiting, and patching. Supposedly some of these heap
managers use mmap as the underlying allocator. So, why aren't they
getting 29 bits, too? :-)

Your measurement of the difference is quite accurate.

There's other allocators, too.

libtalloc:
$ ./all-bits
heap       14 bits
pie-heap   29 bits

Hoard:
$ ./all-bits
heap       25 bits
pie-heap   25 bits

tcmalloc:
$ ./all-bits 
heap       11 bits
pie-heap   26 bits

and just so they are all in one place:

jemalloc:
$ ./all-bits 
heap       19 bits
pie-heap   19 bits

glibc:
$ ./all-bits 
heap       14 bits
pie-heap   29 bits

Are there any other allocators in common use?

This is quite a range in heap ASLR just based on which library you link 
against. Might be nice if some of the low performers gain some more bits of 
randomness.

By the way, you can verify my hypothesis about jemalloc's chunk size by
setting it in the test program. This will be the same as the default:

    #include <stdlib.h>

    // 4MiB (1 << 22)
    //
    // ASLR entropy loss is lg_chunk - page_shift, so 10 bits by default
    const char *malloc_conf = "lg_chunk:22";

    int main() {
        void *p = malloc(16);
        free(p);
    }

I think you should get back 1 bit of entropy for each decrement. The
lowest you can go is 16k, which reduces entropy by 2 bits (so 27 bits
with the vanilla kernel ASLR).

I don't see a way to get it back beyond jemalloc doing low entropy ASLR
internally, and it's not at all obvious how to fit that into the design
in a cheap way.

I expect that the same thing can be caused by making aligned
allocations. If you make a 4M naturally aligned allocation via an API
like posix_memalign, the allocator will probably mmap 4M + the maximum
excess. If it unmaps the excess memory at the head/tail, then it will
have wiped out 10 bits of entropy for future mmap allocations because
the tail will always be at a 4M boundary.

Attachment: signature.asc
Description: OpenPGP digital signature


Current thread: