00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <unistd.h>
00005 #include <setjmp.h>
00006 #include <signal.h>
00007
00008 #include <efence.h>
00009
00010
00011
00012
00013
00014
00015 #ifndef PAGE_PROTECTION_VIOLATED_SIGNAL
00016 #define PAGE_PROTECTION_VIOLATED_SIGNAL SIGSEGV
00017 #endif
00018
00019 struct diagnostic {
00020 int (*test)(void);
00021 int expectedStatus;
00022 const char * explanation;
00023 };
00024
00025 extern int EF_PROTECT_BELOW;
00026 extern int EF_ALIGNMENT;
00027
00028 static jmp_buf env;
00029
00030
00031
00032
00033
00034 static
00035 void
00036 segmentationFaultHandler(
00037 int signalNumber
00038 #if ( defined(_AIX) )
00039 , ...
00040 #endif
00041 )
00042 {
00043 signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
00044 longjmp(env, 1);
00045 }
00046
00047 static int
00048 gotSegmentationFault(int (*test)(void))
00049 {
00050 if ( setjmp(env) == 0 ) {
00051 int status;
00052
00053 signal(PAGE_PROTECTION_VIOLATED_SIGNAL
00054 ,segmentationFaultHandler);
00055 status = (*test)();
00056 signal(PAGE_PROTECTION_VIOLATED_SIGNAL, SIG_DFL);
00057 return status;
00058 }
00059 else
00060 return 1;
00061 }
00062
00063 static char * allocation;
00064
00065 char c;
00066
00067 static int
00068 testSizes(void)
00069 {
00070
00071
00072
00073
00074
00075 return ( sizeof(ef_number) < sizeof(void *) );
00076 }
00077
00078 static int
00079 allocateMemory(void)
00080 {
00081 allocation = (char *)malloc(1);
00082
00083 if ( allocation != 0 )
00084 return 0;
00085 else
00086 return 1;
00087 }
00088
00089 static int
00090 freeMemory(void)
00091 {
00092 free(allocation);
00093 return 0;
00094 }
00095
00096 static int
00097 protectBelow(void)
00098 {
00099 EF_PROTECT_BELOW = 1;
00100 return 0;
00101 }
00102
00103 static int
00104 read0(void)
00105 {
00106 c = *allocation;
00107
00108 return 0;
00109 }
00110
00111 static int
00112 write0(void)
00113 {
00114 *allocation = 1;
00115
00116 return 0;
00117 }
00118
00119 static int
00120 read1(void)
00121 {
00122 c = allocation[1];
00123
00124 return 0;
00125 }
00126
00127 static int
00128 readMinus1(void)
00129 {
00130 c = allocation[-1];
00131 return 0;
00132 }
00133
00134 static struct diagnostic diagnostics[] = {
00135 {
00136 testSizes, 0,
00137 "Please add -DLONG_LONG to the compiler flags and recompile."
00138 },
00139 {
00140 allocateMemory, 0,
00141 "Allocation 1: This test allocates a single byte of memory."
00142 },
00143 {
00144 read0, 0,
00145 "Read valid memory 1: This test reads the allocated memory."
00146 },
00147 {
00148 write0, 0,
00149 "Write valid memory 1: This test writes the allocated memory."
00150 },
00151 {
00152 read1, 1,
00153 "Read overrun: This test reads beyond the end of the buffer."
00154 },
00155 {
00156 freeMemory, 0,
00157 "Free memory: This test frees the allocated memory."
00158 },
00159 {
00160 protectBelow, 0,
00161 "Protect below: This sets Electric Fence to protect\n"
00162 "the lower boundary of a malloc buffer, rather than the\n"
00163 "upper boundary."
00164 },
00165 {
00166 allocateMemory, 0,
00167 "Allocation 2: This allocates memory with the lower boundary"
00168 " protected."
00169 },
00170 {
00171 read0, 0,
00172 "Read valid memory 2: This test reads the allocated memory."
00173 },
00174 {
00175 write0, 0,
00176 "Write valid memory 2: This test writes the allocated memory."
00177 },
00178 {
00179 readMinus1, 1,
00180 "Read underrun: This test reads before the beginning of the"
00181 " buffer."
00182 },
00183 {
00184 0, 0, 0
00185 }
00186 };
00187
00188 static const char failedTest[]
00189 = "Electric Fence confidence test failed.\n";
00190
00191 static const char newline = '\n';
00192
00193 int
00194 main(int argc, char * * argv)
00195 {
00196 static const struct diagnostic * diag = diagnostics;
00197
00198
00199 EF_PROTECT_BELOW = 0;
00200 EF_ALIGNMENT = 0;
00201
00202 while ( diag->explanation != 0 ) {
00203 int status = gotSegmentationFault(diag->test);
00204
00205 if ( status != diag->expectedStatus ) {
00206
00207
00208
00209
00210
00211
00212 write(2, failedTest, sizeof(failedTest) - 1);
00213 write(2, diag->explanation, strlen(diag->explanation));
00214 write(2, &newline, 1);
00215 _exit(-1);
00216 }
00217 diag++;
00218 }
00219 return 0;
00220 }