ssp.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #ifdef _POSIX_SOURCE
  6. #include <signal.h>
  7. #endif
  8. #if defined(HAVE_SYSLOG)
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <sys/un.h>
  12. #include <sys/syslog.h>
  13. #ifndef _PATH_LOG
  14. #define _PATH_LOG "/dev/log"
  15. #endif
  16. #endif
  17. long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  18. void __guard_setup (void)
  19. {
  20. int fd;
  21. if (__guard[0]!=0) return;
  22. fd = open ("/dev/urandom", 0);
  23. if (fd != -1) {
  24. ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
  25. close (fd) ;
  26. if (size == sizeof(__guard)) return;
  27. }
  28. /* If a random generator can't be used, the protector switches the guard
  29. to the "terminator canary" */
  30. ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
  31. ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
  32. }
  33. void __stack_smash_handler (char func[], int damaged)
  34. {
  35. #if defined (__GNU_LIBRARY__)
  36. extern char * __progname;
  37. #endif
  38. const char message[] = ": stack smashing attack in function ";
  39. int bufsz = 512, len;
  40. char buf[bufsz];
  41. #if defined(HAVE_SYSLOG)
  42. int LogFile;
  43. struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */
  44. #endif
  45. #ifdef _POSIX_SOURCE
  46. {
  47. sigset_t mask;
  48. sigfillset(&mask);
  49. sigdelset(&mask, SIGABRT); /* Block all signal handlers */
  50. sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
  51. }
  52. #endif
  53. strcpy(buf, "<2>"); len=3; /* send LOG_CRIT */
  54. #if defined (__GNU_LIBRARY__)
  55. strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
  56. #endif
  57. if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
  58. if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);}
  59. /* print error message */
  60. write (STDERR_FILENO, buf+3, len-3);
  61. #if defined(HAVE_SYSLOG)
  62. if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
  63. /*
  64. * Send "found" message to the "/dev/log" path
  65. */
  66. SyslogAddr.sun_family = AF_UNIX;
  67. (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
  68. sizeof(SyslogAddr.sun_path) - 1);
  69. SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
  70. sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr,
  71. sizeof(SyslogAddr));
  72. }
  73. #endif
  74. #ifdef _POSIX_SOURCE
  75. { /* Make sure the default handler is associated with SIGABRT */
  76. struct sigaction sa;
  77. memset(&sa, 0, sizeof(struct sigaction));
  78. sigfillset(&sa.sa_mask); /* Block all signals */
  79. sa.sa_flags = 0;
  80. sa.sa_handler = SIG_DFL;
  81. sigaction(SIGABRT, &sa, NULL);
  82. (void)kill(getpid(), SIGABRT);
  83. }
  84. #endif
  85. _exit(127);
  86. }