提交 58aa5f45 编写于 作者: R Rich Felker

overhaul SSP support to use a real canary

pthread structure has been adjusted to match the glibc/GCC abi for
where the canary is stored on i386 and x86_64. it will need variants
for other archs to provide the added security of the canary's entropy,
but even without that it still works as well as the old "minimal" ssp
support. eventually such changes will be made anyway, since they are
also needed for GCC/C11 thread-local storage support (not yet
implemented).

care is taken not to attempt initializing the thread pointer unless
the program actually uses SSP (by reference to __stack_chk_fail).
上级 e765239f
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define AUX_CNT 24 #define AUX_CNT 24
void dummy(void) void dummy(size_t *auxv)
{ {
} }
weak_alias(dummy, __init_ssp); weak_alias(dummy, __init_ssp);
...@@ -18,7 +18,9 @@ void __init_security(size_t *auxv) ...@@ -18,7 +18,9 @@ void __init_security(size_t *auxv)
size_t i, aux[AUX_CNT] = { 0 }; size_t i, aux[AUX_CNT] = { 0 };
struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
__init_ssp(); #ifndef SHARED
__init_ssp(auxv);
#endif
for (; auxv[0]; auxv+=2) if (auxv[0]<AUX_CNT) aux[auxv[0]] = auxv[1]; for (; auxv[0]; auxv+=2) if (auxv[0]<AUX_CNT) aux[auxv[0]] = auxv[1];
if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
......
#include <string.h>
#include <inttypes.h>
#include <elf.h>
#include "pthread_impl.h" #include "pthread_impl.h"
#include "atomic.h" #include "atomic.h"
void __init_ssp(void) uintptr_t __stack_chk_guard;
void __init_ssp(size_t *auxv)
{ {
#ifndef __PIC__ size_t i;
__pthread_self_init(); pthread_t self = __pthread_self_init();
#endif uintptr_t canary;
for (i=0; auxv[i] && auxv[i]!=AT_RANDOM; i+=2);
if (auxv[i]) memcpy(&canary, (void *)auxv[i+1], sizeof canary);
else canary = (uintptr_t)&canary * 1103515245;
__stack_chk_guard = self->canary = canary;
} }
void __stack_chk_fail(void) void __stack_chk_fail(void)
......
#include <inttypes.h>
uintptr_t __stack_chk_guard = 0xdecafbad;
...@@ -22,8 +22,12 @@ ...@@ -22,8 +22,12 @@
struct pthread { struct pthread {
struct pthread *self; struct pthread *self;
void *dtv, *unused1, *unused2;
uintptr_t sysinfo;
uintptr_t canary;
pid_t tid, pid; pid_t tid, pid;
int tsd_used, errno_val, *errno_ptr; int tsd_used, errno_val, *errno_ptr;
/* All cancellation-related fields must remain together, in order */
volatile uintptr_t cp_sp, cp_ip; volatile uintptr_t cp_sp, cp_ip;
volatile int cancel, canceldisable, cancelasync; volatile int cancel, canceldisable, cancelasync;
unsigned char *map_base; unsigned char *map_base;
......
...@@ -67,8 +67,7 @@ struct dso { ...@@ -67,8 +67,7 @@ struct dso {
char buf[]; char buf[];
}; };
struct __pthread; void __init_ssp(size_t *);
struct __pthread *__pthread_self_init(void);
static struct dso *head, *tail, *libc; static struct dso *head, *tail, *libc;
static char *env_path, *sys_path, *r_path; static char *env_path, *sys_path, *r_path;
...@@ -633,6 +632,8 @@ void *__dynlink(int argc, char **argv) ...@@ -633,6 +632,8 @@ void *__dynlink(int argc, char **argv)
debug.state = 0; debug.state = 0;
_dl_debug_state(); _dl_debug_state();
if (ssp_used) __init_ssp(auxv);
do_init_fini(tail); do_init_fini(tail);
if (!rtld_used) { if (!rtld_used) {
...@@ -641,8 +642,6 @@ void *__dynlink(int argc, char **argv) ...@@ -641,8 +642,6 @@ void *__dynlink(int argc, char **argv)
reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos); reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos);
} }
if (ssp_used) __pthread_self_init();
errno = 0; errno = 0;
return (void *)aux[AT_ENTRY]; return (void *)aux[AT_ENTRY];
} }
......
...@@ -120,6 +120,7 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo ...@@ -120,6 +120,7 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo
new->tsd = (void *)tsd; new->tsd = (void *)tsd;
if (attr) new->detached = attr->_a_detach; if (attr) new->detached = attr->_a_detach;
new->unblock_cancel = self->cancel; new->unblock_cancel = self->cancel;
new->canary = self->canary ^ (uintptr_t)&new;
stack = (void *)new; stack = (void *)new;
__synccall_lock(); __synccall_lock();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册