ssp.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Distributed under the terms of the GNU Lesser General Public License
  3. * $Header: $
  4. *
  5. * This is a modified version of Hiroaki Etoh's stack smashing routines
  6. * implemented for glibc.
  7. *
  8. * The following people have contributed input to this code.
  9. * Ned Ludd - <solar[@]gentoo.org>
  10. * Alexander Gabert - <pappy[@]gentoo.org>
  11. * The PaX Team - <pageexec[@]freemail.hu>
  12. * Peter S. Mazinger - <ps.m[@]gmx.net>
  13. * Yoann Vandoorselaere - <yoann[@]prelude-ids.org>
  14. * Robert Connolly - <robert[@]linuxfromscratch.org>
  15. * Cory Visi <cory[@]visi.name>
  16. * Mike Frysinger <vapier[@]gentoo.org>
  17. */
  18. #if defined __SSP__ || defined __SSP_ALL__
  19. #error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector"
  20. #endif
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <signal.h>
  24. #ifdef __UCLIBC_HAS_SYSLOG__
  25. #include <sys/syslog.h>
  26. #endif
  27. #ifdef __PROPOLICE_BLOCK_SEGV__
  28. # define SSP_SIGTYPE SIGSEGV
  29. #else
  30. # define SSP_SIGTYPE SIGABRT
  31. #endif
  32. static void do_write(const char *msg)
  33. {
  34. /* could use inlined syscall here to be sure ... */
  35. return (void) write(STDERR_FILENO, msg, strlen(msg));
  36. }
  37. static void __cold do_msg(const char *msg1, const char *msg2, const char *msg3)
  38. {
  39. do_write(msg1);
  40. do_write(msg2);
  41. do_write(msg3);
  42. do_write("\n");
  43. #ifdef __UCLIBC_HAS_SYSLOG__
  44. syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3);
  45. #endif
  46. }
  47. static void __cold attribute_noreturn
  48. ssp_handler(void)
  49. {
  50. pid_t pid;
  51. static const char msg_ssd[] = "*** stack smashing detected ***: ";
  52. static const char msg_terminated[] = " terminated";
  53. #ifdef __DODEBUG__
  54. struct sigaction sa;
  55. sigset_t mask;
  56. __sigfillset(&mask);
  57. __sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */
  58. sigprocmask(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */
  59. #endif
  60. do_msg(msg_ssd, __uclibc_progname, msg_terminated);
  61. pid = getpid();
  62. #ifdef __DODEBUG__
  63. /* Make the default handler associated with the signal handler */
  64. memset(&sa, 0, sizeof(sa));
  65. __sigfillset(&sa.sa_mask); /* Block all signals */
  66. if (SIG_DFL) /* if it's constant zero, it's already done */
  67. sa.sa_handler = SIG_DFL;
  68. if (sigaction(SSP_SIGTYPE, &sa, NULL) == 0)
  69. (void)kill(pid, SSP_SIGTYPE);
  70. #endif
  71. (void)kill(pid, SIGKILL);
  72. /* The loop is added only to keep gcc happy. */
  73. while(1)
  74. _exit(127);
  75. }
  76. strong_alias(ssp_handler,__stack_chk_fail)
  77. #ifdef __UCLIBC_HAS_FORTIFY__
  78. /* should be redone when activated to use common code above.
  79. * for now, it works without debugging support */
  80. void __chk_fail(void)
  81. {
  82. static const char msg_fail[] = "*** buffer overflow detected ***: ";
  83. static const char msg_terminated[] = " terminated";
  84. pid_t pid;
  85. do_msg(msg_fail, __uclibc_progname, msg_terminated);
  86. pid = getpid();
  87. (void)kill(pid, SIGKILL);
  88. /* The loop is added only to keep gcc happy. */
  89. while(1)
  90. _exit(127);
  91. }
  92. libc_hidden_def(__chk_fail)
  93. #endif