This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/22853] New: Heap address of pthread_create thread is aligned.


https://sourceware.org/bugzilla/show_bug.cgi?id=22853

            Bug ID: 22853
           Summary: Heap address of pthread_create thread is aligned.
           Product: glibc
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: nptl
          Assignee: unassigned at sourceware dot org
          Reporter: blackzert at gmail dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

When pthread_create'ed thread firstly calls malloc, glibc create a new heap
region for it. Size of this heap depends on compile-time configuration and in
my case ( x84-64 arch ) HEAP_MAX_SIZE is 64MB

In function malloc/arena.c:new_heap there is a condigion when heap will be
aligned by HEAP_MAX_SIZE. This means that address of created heap will be
aligned to HEAP_MAX_SIZE what is 64MB in my case.

Now we can compute the probability to guess the heap address by attacker.

2^48 - 4096 is size of user-mode task. 64MB is 2^26 that means there is
48-26=22, 2^22 possible heaps in the application.
For many Linux distributives mmap_rnd_bits is 28 (tunable with
/proc/sys/vm/mmap_rnd_bits ). It means for such systems 8 hi-bits would be set
- 48 bits - (mmap_rnd_bits + PAGE_SHIFT) = 8, this means we know 8 hi bits of
mmap_base address - it will be started from 0x7f.
What does it means? it means that if application create thread and call malloc
from new thread, it is 2^14 possible values for such heap.

Proof of Concept:

first get program that outputs malloc addr:

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>

void * first(void *x)
{
       int a = (int)x;
       int *p_a = &a;

        void *ptr;
       ptr = malloc(8);
       if (ptr == 0)
       {
               printf("Failed to alloc %d\n", errno);
               return -1;
       }
        printf("%p\n", ptr);
       return 0;
}

int main()
{
       int res;
       pthread_t one;

       res = pthread_create(&one, NULL, &first, 0);
       if (res)
       {
               printf("Failed create thread %d\n", errno);
               return -1;
       }
       void *val;
       pthread_join(one,&val);
       return 0;
}

now execute it many times and get histogram with python:

import subprocess

d = {}
i = 0
while i < 1000000:
   output = subprocess.check_output('./thread_stack_heap_hysto')
   key = int(output, 16)
   if key in d:
       d[key] += 1
   else:
       d[key] = 1
   i += 1
print 'total: ', len(d)
for key in d:
   print hex(key), d[key]


and the result:
$ python get_hysto.py
total:  16385
…

16385 is 0x4001, and 1 here is because max address of kernel for 1 page less
then 2^48.

Summary, heap should not be aligned on 64 megabytes, this behaviour allows
attacker to brute force heap of pthread created thread.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]