Rtld on diet part 1:

Provide rtld-private implementations of __stack_chk_guard,
__stack_chk_fail() and __chk_fail() symbols, to be used by functions
linked from libc_pic.a.  This avoids use of libc stack_protector.c,
which pulls in syslog(3) and stdio as dependency.

Also, do initialize rtld-private copy __stack_chk_guard, previously
libc-provided one was not initialized, since we do not call rtld
object _init() methods.

Reviewed by:	kan
MFC after:	3 weeks
This commit is contained in:
Konstantin Belousov 2012-03-12 12:15:47 +00:00
parent 62a9fc76df
commit ef5cdcbd69

View File

@ -196,6 +196,8 @@ extern Elf_Dyn _DYNAMIC;
int osreldate, pagesize;
long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static int stack_prot = PROT_READ | PROT_WRITE | RTLD_DEFAULT_STACK_EXEC;
static int max_stack_flags;
@ -311,6 +313,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
Obj_Entry **preload_tail;
Objlist initlist;
RtldLockState lockstate;
int mib[2];
size_t len;
/*
* On entry, the dynamic linker itself has not been relocated yet.
@ -346,6 +350,26 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
main_argc = argc;
main_argv = argv;
if (aux_info[AT_CANARY]->a_un.a_ptr != NULL) {
i = aux_info[AT_CANARYLEN]->a_un.a_val;
if (i > sizeof(__stack_chk_guard))
i = sizeof(__stack_chk_guard);
memcpy(__stack_chk_guard, aux_info[AT_CANARY]->a_un.a_ptr, i);
} else {
mib[0] = CTL_KERN;
mib[1] = KERN_ARND;
len = sizeof(__stack_chk_guard);
if (sysctl(mib, 2, __stack_chk_guard, &len, NULL, 0) == -1 ||
len != sizeof(__stack_chk_guard)) {
/* If sysctl was unsuccessful, use the "terminator canary". */
((unsigned char *)(void *)__stack_chk_guard)[0] = 0;
((unsigned char *)(void *)__stack_chk_guard)[1] = 0;
((unsigned char *)(void *)__stack_chk_guard)[2] = '\n';
((unsigned char *)(void *)__stack_chk_guard)[3] = 255;
}
}
trust = !issetugid();
ld_bind_now = getenv(LD_ "BIND_NOW");
@ -4313,3 +4337,19 @@ void
__pthread_cxa_finalize(struct dl_phdr_info *a)
{
}
void
__stack_chk_fail(void)
{
_rtld_error("stack overflow detected; terminated");
die();
}
void
__chk_fail(void)
{
_rtld_error("buffer overflow detected; terminated");
die();
}