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>
This commit is contained in:
parent
1bbdb3c953
commit
0a5dfdbd1b
|
@ -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
|
Loading…
Reference in New Issue