Annotation of embedaddon/ntp/ElectricFence/eftest.c, revision 1.1
1.1 ! misho 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>