[Bug nptl/22852] New: Thread stack and heap caches

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug nptl/22852] New: Thread stack and heap caches

fweimer at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=22852

            Bug ID: 22852
           Summary: Thread stack and heap caches
           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: ---

In current implementation for any thread created with pthread_create glibc will
create a new heap after the first malloc call from context of this thread.
GNU Libc have special caches to keep stacks of finished threads and there's
heaps. This caches allow glibc make faster creation of threads and its heaps.
On any call to pthread_create or malloc from thread glibc first checks
appropriated caches in hope to find already mmaped regions. And if find any use
them.

The problem here is this behaviour totally breaks ASLR - if attacker can leak
address of ended thread stack or heap, he can use this address later in any
vulnerability in hope to get the same stack region / heap memory region and
successfully exploit application.

Current kernel implementation of ASLR is going to be improved I hope. I
prepared patches which will random addresses returned by kernel on any mmap.

Here is Proof of Concepts:

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

void * func(void *x)
{
        long a[1024];
        printf("addr: %p\n", &a[0]);
        if (x)
                printf("value %lx\n", a[0]);
        else
        {
                a[0] = 0xdeadbeef;
                printf("value %lx\n", a[0]);
        }
        void * addr = malloc(32);
        printf("malloced %p\n", addr);
        free(addr);
        return 0;
}

int main(int argc, char **argv, char **envp)
{
   int res, val;
        pthread_t thread;
        res = pthread_create(&thread, NULL, func, 0);
        if (res)
        {
                printf("Failed create thread %d\n", errno);
                return -1;
        }
        pthread_join(thread, &val);
        res = pthread_create(&thread, NULL, func, 1);
        if (res)
        {
                printf("Failed create thread %d\n", errno);
                return -1;
        }
        pthread_join(thread, &val);
        return 0;
}

and run:
blackzert@crasher:~/aslur/tests$ ./pthread_cache
addr: 0x7ffb90c52f40
value deadbeef
malloced 0x7ffb8c000cd0
addr: 0x7ffb90c52f40
value deadbeef
malloced 0x7ffb8c000cd0

with strace:
blackzert@crasher:~/aslur/tests$ strace -e mmap,munmap ./pthread_cache
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f134346d000
mmap(NULL, 146377, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1343449000
mmap(NULL, 2212904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) =
0x7f134302d000
mmap(0x7f1343244000, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f1343244000
mmap(0x7f1343246000, 13352, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1343246000
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) =
0x7f1342c63000
mmap(0x7f1343023000, 24576, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f1343023000
mmap(0x7f1343029000, 14752, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1343029000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f1343448000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f1343447000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f1343446000
munmap(0x7f1343449000, 146377)          = 0
mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,
-1, 0) = 0x7f1342462000
addr: 0x7f1342c5ff40
value deadbeef
malloced 0x7f133c000cd0
addr: 0x7f1342c5ff40
value deadbeef
malloced 0x7f133c000cd0
+++ exited with 0 +++

As you can see no mmap call between allocation.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug nptl/22852] Thread stack and heap caches

fweimer at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=22852

Ilya Smith <blackzert at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |blackzert at gmail dot com

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug nptl/22852] Thread stack and heap caches

fweimer at redhat dot com
In reply to this post by fweimer at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=22852

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fweimer at redhat dot com
              Flags|                            |security-

--- Comment #1 from Florian Weimer <fweimer at redhat dot com> ---
Flagging as security- because this is a request for additional hardening.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug nptl/22852] Thread stack and heap caches

fweimer at redhat dot com
In reply to this post by fweimer at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=22852

--- Comment #2 from Ilya Smith <blackzert at gmail dot com> ---
Hello,

Can you please explain me what exactly this hardening is?
If this hardening of security, this should be a security bug,
But if you think something different, please explain me.

From my point of view this bug only about security because lead to ASLR bypass
or in some cases may be used as exploitation technique.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug nptl/22852] Thread stack and heap caches

fweimer at redhat dot com
In reply to this post by fweimer at redhat dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=22852

Andreas Schwab <[hidden email]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
              Alias|                            |CVE-2019-1010024

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