/*****************************************************************************
 * Copyright (C) 2005  Remi Denis-Courmont.  All rights reserved.            *
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 * 2. Redistribution in binary form must reproduce the above copyright       *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * The situation as regards scientific and technical know-how at the time    *
 * when this software was distributed did not enable all possible uses to be *
 * tested and verified, nor for the presence of any or all faults to be      *
 * detected. In this respect, people's attention is drawn to the risks       *
 * associated with loading, using, modifying and/or developing and           *
 * reproducing this software.                                                *
 * The user shall be responsible for verifying, by any or all means, the     *
 * software's suitability for its requirements, its due and proper           *
 * functioning, and for ensuring that it shall not cause damage to either    *
 * persons or property.                                                      *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 *                                                                           *
 * The author does not either expressly or tacitly warrant that this         *
 * software does not infringe any or all third party intellectual right      *
 * relating to a patent, software or to any or all other property right.     *
 * Moreover, the author shall not hold someone harmless against any or all   *
 * proceedings for infringement that may be instituted in respect of the     *
 * use, modification and redistrbution of this software.                     *
 *****************************************************************************/

#define _GNU_SOURCE
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

static void
test (void)
{
}


static void
runstack (void)
{
	char buf[4096];

	memcpy (buf, test, sizeof (buf));
	((void (*) (void)) (buf)) ();
}


int
main (void)
{
	int status;

	fputs ("Trying to run code on stack... ", stdout);
	fflush (stdout);
	switch (fork ())
	{
		case -1:
			perror ("fork");
			return 2;

		case 0:
			runstack ();
			exit (0);
	}

	wait (&status);
	if (WIFEXITED (status))
	{
		puts ("OK");
		puts ("Stack smashing protection NOT present.");
		return 1;
	}

	status = WTERMSIG (status);
	printf ("Failed (signal %d (%s) caught).\n", status,
		strsignal (status));
	if (status == SIGKILL)
	{
		
		puts ("Your O.S. forbids stack-based execution.");
		return 0;
	}
	if (status == SIGSEGV)
	{
		puts ("Your architecture prevents stack-based execution.");
		return 0;
	}
	puts ("Unexpected error. Check failed.");

	return 2;
}

