File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ElectricFence / eftest.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 5 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: #include <stdlib.h>
    2: #include <stdio.h>
    3: #include <string.h>
    4: #include <unistd.h>
    5: #include <setjmp.h>
    6: #include <signal.h>
    7: #include "efence.h"
    8: 
    9: /*
   10:  * Electric Fence confidence tests.
   11:  * Make sure all of the various functions of Electric Fence work correctly.
   12:  */
   13: 
   14: #ifndef	PAGE_PROTECTION_VIOLATED_SIGNAL
   15: #define	PAGE_PROTECTION_VIOLATED_SIGNAL	SIGSEGV
   16: #endif
   17: 
   18: struct diagnostic {
   19: 	int		(*test)(void);
   20: 	int		expectedStatus;
   21: 	const char *	explanation;
   22: };
   23: 
   24: extern int	EF_PROTECT_BELOW;
   25: extern int	EF_ALIGNMENT;
   26: 
   27: static jmp_buf	env;
   28: 
   29: /*
   30:  * There is still too little standardization of the arguments and return
   31:  * type of signal handler functions.
   32:  */
   33: static
   34: void
   35: segmentationFaultHandler(
   36: int signalNumber
   37: #if ( defined(_AIX) )
   38: , ...
   39: #endif
   40: )
   41:  {
   42: 	signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
   43: 	longjmp(env, 1);
   44: }
   45: 
   46: static int
   47: gotSegmentationFault(int (*test)(void))
   48: {
   49: 	if ( setjmp(env) == 0 ) {
   50: 		int			status;
   51: 
   52: 		signal(PAGE_PROTECTION_VIOLATED_SIGNAL
   53: 		,segmentationFaultHandler);
   54: 		status = (*test)();
   55: 		signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
   56: 		return status;
   57: 	}
   58: 	else
   59: 		return 1;
   60: }
   61: 
   62: static char *	allocation;
   63: /* c is global so that assignments to it won't be optimized out. */
   64: char	c;
   65: 
   66: static int
   67: testSizes(void)
   68: {
   69: 	/*
   70: 	 * If ef_number can't hold all of the bits of a void *, have the user
   71: 	 * add -DUSE_ LONG_LONG to the compiler flags so that ef_number will be
   72: 	 * declared as "unsigned long long" instead of "unsigned long".
   73: 	 */
   74: 	return ( sizeof(ef_number) < sizeof(void *) );
   75: }
   76: 
   77: static int
   78: allocateMemory(void)
   79: {
   80: 	allocation = (char *)malloc(1);
   81: 
   82: 	if ( allocation != 0 )
   83: 		return 0;
   84: 	else
   85: 		return 1;
   86: }
   87: 
   88: static int
   89: freeMemory(void)
   90: {
   91: 	free(allocation);
   92: 	return 0;
   93: }
   94: 
   95: static int
   96: protectBelow(void)
   97: {
   98: 	EF_PROTECT_BELOW = 1;
   99: 	return 0;
  100: }
  101: 
  102: static int
  103: read0(void)
  104: {
  105: 	c = *allocation;
  106: 
  107: 	return 0;
  108: }
  109: 
  110: static int
  111: write0(void)
  112: {
  113: 	*allocation = 1;
  114: 
  115: 	return 0;
  116: }
  117: 
  118: static int
  119: read1(void)
  120: {
  121: 	c = allocation[1];
  122: 
  123: 	return 0;
  124: }
  125: 
  126: static int
  127: readMinus1(void)
  128: {
  129: 	c = allocation[-1];
  130: 	return 0;
  131: }
  132: 
  133: static struct diagnostic diagnostics[] = {
  134: 	{
  135: 		testSizes, 0,
  136: 		"Please add -DLONG_LONG to the compiler flags and recompile."
  137: 	},
  138: 	{
  139: 		allocateMemory, 0,
  140: 		"Allocation 1: This test allocates a single byte of memory."
  141: 	},
  142: 	{
  143: 		read0, 0,
  144: 		"Read valid memory 1: This test reads the allocated memory."
  145: 	},
  146: 	{
  147: 		write0, 0,
  148: 		"Write valid memory 1: This test writes the allocated memory."
  149: 	},
  150: 	{
  151: 		read1, 1,
  152: 		"Read overrun: This test reads beyond the end of the buffer."
  153: 	},
  154: 	{
  155: 		freeMemory, 0,
  156: 		"Free memory: This test frees the allocated memory."
  157: 	},
  158: 	{
  159: 		protectBelow, 0,
  160: 		"Protect below: This sets Electric Fence to protect\n"
  161: 		"the lower boundary of a malloc buffer, rather than the\n"
  162: 		"upper boundary."
  163: 	},
  164: 	{
  165: 		allocateMemory, 0,
  166: 		"Allocation 2: This allocates memory with the lower boundary"
  167: 		" protected."
  168: 	},
  169: 	{
  170: 		read0, 0,
  171: 		"Read valid memory 2: This test reads the allocated memory."
  172: 	},
  173: 	{
  174: 		write0, 0,
  175: 		"Write valid memory 2: This test writes the allocated memory."
  176: 	},
  177: 	{
  178: 		readMinus1, 1,
  179: 		"Read underrun: This test reads before the beginning of the"
  180: 		" buffer."
  181: 	},
  182: 	{
  183: 		0, 0, 0
  184: 	}
  185: };
  186: 
  187: static const char	failedTest[]
  188:  = "Electric Fence confidence test failed.\n";
  189: 
  190: static const char	newline = '\n';
  191: 
  192: int
  193: main(int argc, char * * argv)
  194: {
  195: 	static const struct diagnostic *	diag = diagnostics;
  196: 	
  197: 
  198: 	EF_PROTECT_BELOW = 0;
  199: 	EF_ALIGNMENT = 0;
  200: 
  201: 	while ( diag->explanation != 0 ) {
  202: 		int	status = gotSegmentationFault(diag->test);
  203: 
  204: 		if ( status != diag->expectedStatus ) {
  205: 			/*
  206: 			 * Don't use stdio to print here, because stdio
  207: 			 * uses malloc() and we've just proven that malloc()
  208: 			 * is broken. Also, use _exit() instead of exit(),
  209: 			 * because _exit() doesn't flush stdio.
  210: 			 */
  211: 			write(2, failedTest, sizeof(failedTest) - 1);
  212: 			write(2, diag->explanation, strlen(diag->explanation));
  213: 			write(2, &newline, 1);
  214: 			_exit(-1);
  215: 		}
  216: 		diag++;
  217: 	}
  218: 	return 0;
  219: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>