1 /* 2 ** 2018-10-26 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** 13 ** This program is designed for fuzz-testing SQLite database files using 14 ** the -fsanitize=fuzzer option of clang. 15 ** 16 ** The -fsanitize=fuzzer option causes a main() to be inserted automatically. 17 ** That main() invokes LLVMFuzzerTestOneInput(D,S) to be invoked repeatedly. 18 ** Each D is a fuzzed database file. The code in this file runs various 19 ** SQL statements against that database, trying to provoke a failure. 20 ** 21 ** For best results the seed database files should have these tables: 22 ** 23 ** Table "t1" with columns "a" and "b" 24 ** Tables "t2" and "t3 with the same number of compatible columns 25 ** "t3" should have a column names "x" 26 ** Table "t4" with a column "x" that is compatible with t3.x. 27 ** 28 ** Any of these tables can be virtual tables, for example FTS or RTree tables. 29 ** 30 ** To run this test: 31 ** 32 ** mkdir dir 33 ** cp dbfuzz2-seed*.db dir 34 ** clang-6.0 -I. -g -O1 -fsanitize=fuzzer \ 35 ** -DTHREADSAFE=0 -DSQLITE_ENABLE_DESERIALIZE \ 36 ** -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl 37 ** ./a.out dir 38 */ 39 #include <assert.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <stdarg.h> 44 #include <ctype.h> 45 #include <stdint.h> 46 #ifndef _WIN32 47 #include <sys/time.h> 48 #include <sys/resource.h> 49 #endif 50 #include "sqlite3.h" 51 52 /* 53 ** This is the is the SQL that is run against the database. 54 */ 55 static const char *azSql[] = { 56 "PRAGMA integrity_check;", 57 "SELECT * FROM sqlite_schema;", 58 "SELECT sum(length(name)) FROM dbstat;", 59 "UPDATE t1 SET b=a, a=b WHERE a<b;", 60 "ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;", 61 "INSERT INTO t3 SELECT * FROM t2;", 62 "DELETE FROM t3 WHERE x IN (SELECT x FROM t4);", 63 "REINDEX;", 64 "DROP TABLE t3;", 65 "VACUUM;", 66 }; 67 68 /* Output verbosity level. 0 means complete silence */ 69 int eVerbosity = 0; 70 71 /* True to activate PRAGMA vdbe_debug=on */ 72 static int bVdbeDebug = 0; 73 74 /* Maximum size of the in-memory database file */ 75 static sqlite3_int64 szMax = 104857600; 76 77 /* Progress handler callback data */ 78 static int nCb = 0; /* Number of callbacks seen so far */ 79 static int mxCb = 250000; /* Maximum allowed callbacks */ 80 81 /***** Copy/paste from ext/misc/memtrace.c ***************************/ 82 /* The original memory allocation routines */ 83 static sqlite3_mem_methods memtraceBase; 84 static FILE *memtraceOut; 85 86 /* Methods that trace memory allocations */ 87 static void *memtraceMalloc(int n){ 88 if( memtraceOut ){ 89 fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", 90 memtraceBase.xRoundup(n)); 91 } 92 return memtraceBase.xMalloc(n); 93 } 94 static void memtraceFree(void *p){ 95 if( p==0 ) return; 96 if( memtraceOut ){ 97 fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p)); 98 } 99 memtraceBase.xFree(p); 100 } 101 static void *memtraceRealloc(void *p, int n){ 102 if( p==0 ) return memtraceMalloc(n); 103 if( n==0 ){ 104 memtraceFree(p); 105 return 0; 106 } 107 if( memtraceOut ){ 108 fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n", 109 memtraceBase.xSize(p), memtraceBase.xRoundup(n)); 110 } 111 return memtraceBase.xRealloc(p, n); 112 } 113 static int memtraceSize(void *p){ 114 return memtraceBase.xSize(p); 115 } 116 static int memtraceRoundup(int n){ 117 return memtraceBase.xRoundup(n); 118 } 119 static int memtraceInit(void *p){ 120 return memtraceBase.xInit(p); 121 } 122 static void memtraceShutdown(void *p){ 123 memtraceBase.xShutdown(p); 124 } 125 126 /* The substitute memory allocator */ 127 static sqlite3_mem_methods ersaztMethods = { 128 memtraceMalloc, 129 memtraceFree, 130 memtraceRealloc, 131 memtraceSize, 132 memtraceRoundup, 133 memtraceInit, 134 memtraceShutdown 135 }; 136 137 /* Begin tracing memory allocations to out. */ 138 int sqlite3MemTraceActivate(FILE *out){ 139 int rc = SQLITE_OK; 140 if( memtraceBase.xMalloc==0 ){ 141 rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase); 142 if( rc==SQLITE_OK ){ 143 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods); 144 } 145 } 146 memtraceOut = out; 147 return rc; 148 } 149 150 /* Deactivate memory tracing */ 151 int sqlite3MemTraceDeactivate(void){ 152 int rc = SQLITE_OK; 153 if( memtraceBase.xMalloc!=0 ){ 154 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase); 155 if( rc==SQLITE_OK ){ 156 memset(&memtraceBase, 0, sizeof(memtraceBase)); 157 } 158 } 159 memtraceOut = 0; 160 return rc; 161 } 162 /***** End copy/paste from ext/misc/memtrace.c ***************************/ 163 164 /* 165 ** Progress handler callback 166 ** 167 ** Count the number of callbacks and cause an abort once the limit is 168 ** reached. 169 */ 170 static int progress_handler(void *pNotUsed){ 171 nCb++; 172 if( nCb<mxCb ) return 0; 173 if( eVerbosity>=1 ){ 174 printf("-- Progress limit of %d reached\n", mxCb); 175 } 176 return 1; 177 } 178 179 /* libFuzzer invokes this routine with fuzzed database files (in aData). 180 ** This routine run SQLite against the malformed database to see if it 181 ** can provoke a failure or malfunction. 182 */ 183 int LLVMFuzzerTestOneInput(const uint8_t *aData, size_t nByte){ 184 unsigned char *a; 185 sqlite3 *db; 186 int rc; 187 int i; 188 sqlite3_int64 x; 189 char *zErr = 0; 190 191 if( eVerbosity>=1 ){ 192 printf("************** nByte=%d ***************\n", (int)nByte); 193 fflush(stdout); 194 } 195 if( sqlite3_initialize() ) return 0; 196 rc = sqlite3_open(0, &db); 197 if( rc ) return 1; 198 a = sqlite3_malloc64(nByte+1); 199 if( a==0 ) return 1; 200 memcpy(a, aData, nByte); 201 sqlite3_deserialize(db, "main", a, nByte, nByte, 202 SQLITE_DESERIALIZE_RESIZEABLE | 203 SQLITE_DESERIALIZE_FREEONCLOSE); 204 x = szMax; 205 #ifdef SQLITE_FCNTL_SIZE_LIMIT 206 sqlite3_file_control(db, "main", SQLITE_FCNTL_SIZE_LIMIT, &x); 207 #endif 208 if( bVdbeDebug ){ 209 sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0); 210 } 211 if( mxCb>0 ){ 212 sqlite3_progress_handler(db, 10, progress_handler, 0); 213 } 214 #ifdef SQLITE_TESTCTRL_PRNG_SEED 215 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db); 216 #endif 217 for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){ 218 if( eVerbosity>=1 ){ 219 printf("%s\n", azSql[i]); 220 fflush(stdout); 221 } 222 zErr = 0; 223 nCb = 0; 224 rc = sqlite3_exec(db, azSql[i], 0, 0, &zErr); 225 if( rc && eVerbosity>=1 ){ 226 printf("-- rc=%d zErr=%s\n", rc, zErr); 227 } 228 sqlite3_free(zErr); 229 } 230 rc = sqlite3_close(db); 231 if( rc!=SQLITE_OK ){ 232 fprintf(stdout, "sqlite3_close() returns %d\n", rc); 233 } 234 if( sqlite3_memory_used()!=0 ){ 235 int nAlloc = 0; 236 int nNotUsed = 0; 237 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0); 238 fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n", 239 sqlite3_memory_used(), nAlloc); 240 exit(1); 241 } 242 return 0; 243 } 244 245 /* 246 ** Return the number of "v" characters in a string. Return 0 if there 247 ** are any characters in the string other than "v". 248 */ 249 static int numberOfVChar(const char *z){ 250 int N = 0; 251 while( z[0] && z[0]=='v' ){ 252 z++; 253 N++; 254 } 255 return z[0]==0 ? N : 0; 256 } 257 258 /* libFuzzer invokes this routine once when the executable starts, to 259 ** process the command-line arguments. 260 */ 261 int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){ 262 int i, j, n; 263 int argc = *pArgc; 264 char **argv = *pArgv; 265 for(i=j=1; i<argc; i++){ 266 char *z = argv[i]; 267 if( z[0]=='-' ){ 268 z++; 269 if( z[0]=='-' ) z++; 270 if( z[0]=='v' && (n = numberOfVChar(z))>0 ){ 271 eVerbosity += n; 272 continue; 273 } 274 if( strcmp(z,"vdbe-debug")==0 ){ 275 bVdbeDebug = 1; 276 continue; 277 } 278 if( strcmp(z,"limit")==0 ){ 279 if( i+1==argc ){ 280 fprintf(stderr, "missing argument to %s\n", argv[i]); 281 exit(1); 282 } 283 mxCb = strtol(argv[++i], 0, 0); 284 continue; 285 } 286 if( strcmp(z,"memtrace")==0 ){ 287 sqlite3MemTraceActivate(stdout); 288 continue; 289 } 290 if( strcmp(z,"mem")==0 ){ 291 bVdbeDebug = 1; 292 continue; 293 } 294 if( strcmp(z,"max-db-size")==0 ){ 295 if( i+1==argc ){ 296 fprintf(stderr, "missing argument to %s\n", argv[i]); 297 exit(1); 298 } 299 szMax = strtol(argv[++i], 0, 0); 300 continue; 301 } 302 #ifndef _WIN32 303 if( strcmp(z,"max-stack")==0 304 || strcmp(z,"max-data")==0 305 || strcmp(z,"max-as")==0 306 ){ 307 struct rlimit x,y; 308 int resource = RLIMIT_STACK; 309 char *zType = "RLIMIT_STACK"; 310 if( i+1==argc ){ 311 fprintf(stderr, "missing argument to %s\n", argv[i]); 312 exit(1); 313 } 314 if( z[4]=='d' ){ 315 resource = RLIMIT_DATA; 316 zType = "RLIMIT_DATA"; 317 } 318 if( z[4]=='a' ){ 319 resource = RLIMIT_AS; 320 zType = "RLIMIT_AS"; 321 } 322 memset(&x,0,sizeof(x)); 323 getrlimit(resource, &x); 324 y.rlim_cur = atoi(argv[++i]); 325 y.rlim_max = x.rlim_cur; 326 setrlimit(resource, &y); 327 memset(&y,0,sizeof(y)); 328 getrlimit(resource, &y); 329 printf("%s changed from %d to %d\n", 330 zType, (int)x.rlim_cur, (int)y.rlim_cur); 331 continue; 332 } 333 #endif /* _WIN32 */ 334 } 335 argv[j++] = argv[i]; 336 } 337 argv[j] = 0; 338 *pArgc = j; 339 return 0; 340 } 341 342 #ifdef STANDALONE 343 /* 344 ** Read an entire file into memory. Space to hold the file comes 345 ** from malloc(). 346 */ 347 static unsigned char *readFile(const char *zName, int *pnByte){ 348 FILE *in = fopen(zName, "rb"); 349 long nIn; 350 size_t nRead; 351 unsigned char *pBuf; 352 if( in==0 ) return 0; 353 fseek(in, 0, SEEK_END); 354 nIn = ftell(in); 355 rewind(in); 356 pBuf = malloc( nIn+1 ); 357 if( pBuf==0 ){ fclose(in); return 0; } 358 nRead = fread(pBuf, nIn, 1, in); 359 fclose(in); 360 if( nRead!=1 ){ 361 free(pBuf); 362 return 0; 363 } 364 pBuf[nIn] = 0; 365 if( pnByte ) *pnByte = nIn; 366 return pBuf; 367 } 368 #endif /* STANDALONE */ 369 370 #ifdef STANDALONE 371 int main(int argc, char **argv){ 372 int i; 373 LLVMFuzzerInitialize(&argc, &argv); 374 for(i=1; i<argc; i++){ 375 unsigned char *pIn; 376 int nIn; 377 pIn = readFile(argv[i], &nIn); 378 if( pIn ){ 379 LLVMFuzzerTestOneInput((const uint8_t*)pIn, (size_t)nIn); 380 free(pIn); 381 } 382 } 383 #ifdef RUSAGE_SELF 384 if( eVerbosity>0 ){ 385 struct rusage x; 386 printf("SQLite %s\n", sqlite3_sourceid()); 387 memset(&x, 0, sizeof(x)); 388 if( getrusage(RUSAGE_SELF, &x)==0 ){ 389 printf("Maximum RSS = %ld KB\n", x.ru_maxrss); 390 } 391 } 392 #endif 393 return 0; 394 } 395 #endif /*STANDALONE*/ 396