Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ASLR still problematic with -lpthread



In article <i66g75$ckh$1%dough.gmane.org@localhost>,
Christos Zoulas <christos%astron.com@localhost> wrote:
>
>The problem is not with ASLR, but with the stupid way that our pthread
>library deals with the stack. With ASLR you get a lot of random stack
>values, this is why the code is exercised. The issue is that if your
>stack base happens to be 0x???02000 for example and your mask is
>stackmask is 0xffe00000, your base pointer calculation ends up below
>the base of the stack (oops)... You can work around the problem 
>unlimiting stacksize, but this stupidity with the stack needs to go,
>and it will.

Here's the disgusting fix; I am not going to even bother to explain it.

Index: pthread.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread.c,v
retrieving revision 1.116
diff -u -u -r1.116 pthread.c
--- pthread.c   8 Jul 2010 15:13:35 -0000       1.116
+++ pthread.c   9 Sep 2010 21:40:02 -0000
@@ -108,6 +108,8 @@
 size_t pthread__stacksize = 1 << _STACKSIZE_LG;
 vaddr_t        pthread__stackmask = (1 << _STACKSIZE_LG) - 1;
 vaddr_t pthread__threadmask = (vaddr_t)~((1 << _STACKSIZE_LG) - 1);
+vaddr_t        pthread__mainbase = 0;
+vaddr_t        pthread__mainstruct = 0;
 #undef _STACKSIZE_LG
 
 int _sys___sigprocmask14(int, const sigset_t *, sigset_t *);
@@ -1221,7 +1223,14 @@
        pthread__threadmask = ~pthread__stackmask;
 
        base = (void *)(pthread__sp() & pthread__threadmask);
+       if ((pthread__sp() - (uintptr_t)base) < 4 * pagesize) {
+               pthread__mainbase = (vaddr_t)base;
+               base = STACK_GROW(base, pthread__stacksize);
+               pthread__mainstruct = (vaddr_t)base;
+       }
        size = pthread__stacksize;
+       if (mprotect(base, size, PROT_READ|PROT_WRITE) == -1)
+               err(1, "mprotect stack");
 
        error = pthread__stackid_setup(base, size, &t);
        if (error) {
Index: pthread_int.h
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_int.h,v
retrieving revision 1.72
diff -u -u -r1.72 pthread_int.h
--- pthread_int.h       17 May 2009 14:49:00 -0000      1.72
+++ pthread_int.h       9 Sep 2010 21:40:03 -0000
@@ -249,13 +249,18 @@
        _INITCONTEXT_U_MD(ucp)                                          \
        } while (/*CONSTCOND*/0)
 
-/* Stack location of pointer to a particular thread */
-#define pthread__id(sp) \
-       ((pthread_t) (((vaddr_t)(sp)) & pthread__threadmask))
 
 #ifdef PTHREAD__HAVE_THREADREG
 #define        pthread__self()         pthread__threadreg_get()
 #else
+/* Stack location of pointer to a particular thread */
+extern vaddr_t pthread__mainbase;
+extern vaddr_t pthread__mainstruct;
+static inline pthread_t
+pthread__id(vaddr_t sp) {
+       vaddr_t va = sp & pthread__threadmask;
+       return (pthread_t)(va == pthread__mainbase ? pthread__mainstruct : va);
+}
 #define pthread__self()        (pthread__id(pthread__sp()))
 #endif
 



Home | Main Index | Thread Index | Old Index