/*
gcc -fstack-protector -fPIC -shared stack_smash_handler.c -o stack_smash_handler.so

pie guard_preload # LD_PRELOAD=$PWD/stack_smash_handler.so ./vuln 012345678901234567
vuln: stack smashing attack in function main pid=13335 ppid=16973 uid=0 euid=0 gid=0 egid=0
Aborted


*/

/*
 * Distributed under the terms of the GNU General Public License v2
 * $Header: $
 *
 * This is a modified version of Hiroaki Etoh's stack smashing routines
 * initialy implemented for glibc by pappy@gentoo.org

 * Dec 14 2003 solar@gentoo.org
 * begin code cleanup for ssp helper functions.
 *
 * Mar 10 2004 -solar
 * Allows the user to choose 1 of 3 signals, to stop an offending program.
 * Attempt to open kernel pseudo random device before urandom.
 * Print semi verbose audit messages for logging systems.
 *
 */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>

#ifdef _POSIX_SOURCE
#include <signal.h>
#endif

#ifdef __PROPOLICE_BLOCK_SEGV__
#define SSP_SIGTYPE SIGSEGV
#elif __PROPOLICE_BLOCK_KILL__
#define SSP_SIGTYPE SIGKILL
#else
#define SSP_SIGTYPE SIGABRT
#endif

#ifndef _POSIX_SOURCE	/* should be defined anyway */
#define _POSIX_SOURCE
#endif

void __stack_smash_handler(char func[], int damaged)
{
#if defined (__GNU_LIBRARY__)
   extern char *__progname;
#else
   char *__progname = "";
#endif

#ifdef _POSIX_SOURCE
   sigset_t mask;
   struct sigaction sa;

   /* Block all signal handlers except signal type */
   sigfillset(&mask);
   sigdelset(&mask, SSP_SIGTYPE);
   sigprocmask(SIG_BLOCK, &mask, NULL);
#endif

   /*
    * print error message
    * please drop a mail to yoann at prelude-ids.org if you change the
    * message, so that prelude-lml signature can be updated.
    */
   fprintf(stderr,		/* nls anyone? */
	   "%s: stack smashing attack in function %s "
	   "pid=%d ppid=%d uid=%d euid=%d gid=%d egid=%d\n",
	   __progname, func, (int) getpid(), (int) getppid(),
	   (int) getuid(), (int) geteuid(), (int) getgid(),
	   (int) getegid());
   syslog(LOG_CRIT | LOG_AUTHPRIV,
	  "%s: stack smashing attack in function %s "
	  "pid=%d ppid=%d uid=%d euid=%d gid=%d egid=%d",
	  __progname, func, (int) getpid(), (int) getppid(),
	  (int) getuid(), (int) geteuid(), (int) getgid(),
	  (int) getegid());

#ifdef _POSIX_SOURCE
   /* Make sure the handler is associated correctly and block all signals */
   memset(&sa, 0, sizeof(struct sigaction));
   sigfillset(&sa.sa_mask);
   sa.sa_flags = 0;
   sa.sa_handler = SIG_DFL;
   sigaction(SSP_SIGTYPE, &sa, NULL);
   (void) kill(getpid(), SSP_SIGTYPE);
#endif

   _exit(127);
   while (1);
}
