diff options
author | Yaakov Selkowitz <yselkowi@redhat.com> | 2017-11-27 23:04:09 -0600 |
---|---|---|
committer | Yaakov Selkowitz <yselkowi@redhat.com> | 2017-11-29 11:25:37 -0600 |
commit | 0a5dfdbd1ba3663a54fa1a7de1a6c4a0a3316a6e (patch) | |
tree | 6938b9d9d6235e9d849ae84578a846507644823e /newlib | |
parent | 1bbdb3c9533684282695e147d0480b771fd13687 (diff) | |
download | newlib-0a5dfdbd1ba3663a54fa1a7de1a6c4a0a3316a6e.zip newlib-0a5dfdbd1ba3663a54fa1a7de1a6c4a0a3316a6e.tar.gz newlib-0a5dfdbd1ba3663a54fa1a7de1a6c4a0a3316a6e.tar.bz2 |
ssp: add APIs for Stack Smashing Protection
Compiling with any of the -fstack-protector* flags requires the
__stack_chk_guard data import (which needs to be initialized) and the
__stack_chk_fail{,_local} functions. While GCC's own libssp can provide
these, it is better that we provide these ourselves. The implementation
is custom due to being OS-specific.
Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
Diffstat (limited to 'newlib')
-rw-r--r-- | newlib/libc/ssp/stack_protector.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c new file mode 100644 index 0000000..ee014b6 --- /dev/null +++ b/newlib/libc/ssp/stack_protector.c @@ -0,0 +1,45 @@ +#include <sys/cdefs.h> +#include <sys/param.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +uintptr_t __stack_chk_guard = 0; + +void +__attribute__((__constructor__)) +__stack_chk_init (void) +{ + if (__stack_chk_guard != 0) + return; + +#if defined(__CYGWIN__) || defined(__rtems__) + arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); +#else + /* If getentropy is not available, use the "terminator canary". */ + ((unsigned char *)&__stack_chk_guard)[0] = 0; + ((unsigned char *)&__stack_chk_guard)[1] = 0; + ((unsigned char *)&__stack_chk_guard)[2] = '\n'; + ((unsigned char *)&__stack_chk_guard)[3] = 255; +#endif +} + +void +__attribute__((__noreturn__)) +__stack_chk_fail (void) +{ + char msg[] = "*** stack smashing detected ***: terminated\n"; + write (2, msg, strlen (msg)); + raise (SIGABRT); + _exit (127); +} + +#ifdef __ELF__ +void +__attribute__((visibility ("hidden"))) +__stack_chk_fail_local (void) +{ + __stack_chk_fail(); +} +#endif |