xref: /sqlite-3.40.0/test/dbfuzz2.c (revision 8d889afc)
165da285eSdrh /*
265da285eSdrh ** 2018-10-26
365da285eSdrh **
465da285eSdrh ** The author disclaims copyright to this source code.  In place of
565da285eSdrh ** a legal notice, here is a blessing:
665da285eSdrh **
765da285eSdrh **    May you do good and not evil.
865da285eSdrh **    May you find forgiveness for yourself and forgive others.
965da285eSdrh **    May you share freely, never taking more than you give.
1065da285eSdrh **
1165da285eSdrh *************************************************************************
1265da285eSdrh **
1365da285eSdrh ** This program is designed for fuzz-testing SQLite database files using
1465da285eSdrh ** the -fsanitize=fuzzer option of clang.
1565da285eSdrh **
1665da285eSdrh ** The -fsanitize=fuzzer option causes a main() to be inserted automatically.
1765da285eSdrh ** That main() invokes LLVMFuzzerTestOneInput(D,S) to be invoked repeatedly.
1865da285eSdrh ** Each D is a fuzzed database file.  The code in this file runs various
1965da285eSdrh ** SQL statements against that database, trying to provoke a failure.
2065da285eSdrh **
2165da285eSdrh ** For best results the seed database files should have these tables:
2265da285eSdrh **
2365da285eSdrh **   Table "t1" with columns "a" and "b"
2465da285eSdrh **   Tables "t2" and "t3 with the same number of compatible columns
2565da285eSdrh **       "t3" should have a column names "x"
2665da285eSdrh **   Table "t4" with a column "x" that is compatible with t3.x.
2765da285eSdrh **
2865da285eSdrh ** Any of these tables can be virtual tables, for example FTS or RTree tables.
2965da285eSdrh **
3065da285eSdrh ** To run this test:
3165da285eSdrh **
3265da285eSdrh **     mkdir dir
3365da285eSdrh **     cp dbfuzz2-seed*.db dir
34*8d889afcSdrh **     clang-6.0 -I. -g -O1 -fsanitize=fuzzer -DTHREADSAFE=0 \
3565da285eSdrh **       -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl
3665da285eSdrh **     ./a.out dir
3765da285eSdrh */
3865da285eSdrh #include <assert.h>
3965da285eSdrh #include <stdio.h>
4065da285eSdrh #include <stdlib.h>
4165da285eSdrh #include <string.h>
4265da285eSdrh #include <stdarg.h>
4365da285eSdrh #include <ctype.h>
4465da285eSdrh #include <stdint.h>
457e85e903Sdrh #ifndef _WIN32
468ed07d12Sdrh #include <sys/time.h>
478ed07d12Sdrh #include <sys/resource.h>
487e85e903Sdrh #endif
4965da285eSdrh #include "sqlite3.h"
5065da285eSdrh 
5165da285eSdrh /*
5265da285eSdrh ** This is the is the SQL that is run against the database.
5365da285eSdrh */
5465da285eSdrh static const char *azSql[] = {
5565da285eSdrh   "PRAGMA integrity_check;",
56067b92baSdrh   "SELECT * FROM sqlite_schema;",
5765da285eSdrh   "SELECT sum(length(name)) FROM dbstat;",
5865da285eSdrh   "UPDATE t1 SET b=a, a=b WHERE a<b;",
59d811d844Sdrh   "ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;",
6065da285eSdrh   "INSERT INTO t3 SELECT * FROM t2;",
6165da285eSdrh   "DELETE FROM t3 WHERE x IN (SELECT x FROM t4);",
62d811d844Sdrh   "REINDEX;",
6365da285eSdrh   "DROP TABLE t3;",
6465da285eSdrh   "VACUUM;",
6565da285eSdrh };
6665da285eSdrh 
67d811d844Sdrh /* Output verbosity level.  0 means complete silence */
68d811d844Sdrh int eVerbosity = 0;
69d811d844Sdrh 
701972c8cfSdrh /* True to activate PRAGMA vdbe_debug=on */
711972c8cfSdrh static int bVdbeDebug = 0;
721972c8cfSdrh 
73178edcd7Sdrh /* Maximum size of the in-memory database file */
74178edcd7Sdrh static sqlite3_int64 szMax = 104857600;
75178edcd7Sdrh 
76fb556712Sdrh /* Progress handler callback data */
77fb556712Sdrh static int nCb = 0;                  /* Number of callbacks seen so far */
78fb556712Sdrh static int mxCb = 250000;            /* Maximum allowed callbacks */
79fb556712Sdrh 
80a790882dSdrh /***** Copy/paste from ext/misc/memtrace.c ***************************/
81a790882dSdrh /* The original memory allocation routines */
82a790882dSdrh static sqlite3_mem_methods memtraceBase;
83a790882dSdrh static FILE *memtraceOut;
84a790882dSdrh 
85a790882dSdrh /* Methods that trace memory allocations */
memtraceMalloc(int n)86a790882dSdrh static void *memtraceMalloc(int n){
87a790882dSdrh   if( memtraceOut ){
88a790882dSdrh     fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
89a790882dSdrh             memtraceBase.xRoundup(n));
90a790882dSdrh   }
91a790882dSdrh   return memtraceBase.xMalloc(n);
92a790882dSdrh }
memtraceFree(void * p)93a790882dSdrh static void memtraceFree(void *p){
94a790882dSdrh   if( p==0 ) return;
95a790882dSdrh   if( memtraceOut ){
96a790882dSdrh     fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
97a790882dSdrh   }
98a790882dSdrh   memtraceBase.xFree(p);
99a790882dSdrh }
memtraceRealloc(void * p,int n)100a790882dSdrh static void *memtraceRealloc(void *p, int n){
101a790882dSdrh   if( p==0 ) return memtraceMalloc(n);
102a790882dSdrh   if( n==0 ){
103a790882dSdrh     memtraceFree(p);
104a790882dSdrh     return 0;
105a790882dSdrh   }
106a790882dSdrh   if( memtraceOut ){
107a790882dSdrh     fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
108a790882dSdrh             memtraceBase.xSize(p), memtraceBase.xRoundup(n));
109a790882dSdrh   }
110a790882dSdrh   return memtraceBase.xRealloc(p, n);
111a790882dSdrh }
memtraceSize(void * p)112a790882dSdrh static int memtraceSize(void *p){
113a790882dSdrh   return memtraceBase.xSize(p);
114a790882dSdrh }
memtraceRoundup(int n)115a790882dSdrh static int memtraceRoundup(int n){
116a790882dSdrh   return memtraceBase.xRoundup(n);
117a790882dSdrh }
memtraceInit(void * p)118a790882dSdrh static int memtraceInit(void *p){
119a790882dSdrh   return memtraceBase.xInit(p);
120a790882dSdrh }
memtraceShutdown(void * p)121a790882dSdrh static void memtraceShutdown(void *p){
122a790882dSdrh   memtraceBase.xShutdown(p);
123a790882dSdrh }
124a790882dSdrh 
125a790882dSdrh /* The substitute memory allocator */
126a790882dSdrh static sqlite3_mem_methods ersaztMethods = {
127a790882dSdrh   memtraceMalloc,
128a790882dSdrh   memtraceFree,
129a790882dSdrh   memtraceRealloc,
130a790882dSdrh   memtraceSize,
131a790882dSdrh   memtraceRoundup,
132a790882dSdrh   memtraceInit,
133a790882dSdrh   memtraceShutdown
134a790882dSdrh };
135a790882dSdrh 
136a790882dSdrh /* Begin tracing memory allocations to out. */
sqlite3MemTraceActivate(FILE * out)137a790882dSdrh int sqlite3MemTraceActivate(FILE *out){
138a790882dSdrh   int rc = SQLITE_OK;
139a790882dSdrh   if( memtraceBase.xMalloc==0 ){
140a790882dSdrh     rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
141a790882dSdrh     if( rc==SQLITE_OK ){
142a790882dSdrh       rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
143a790882dSdrh     }
144a790882dSdrh   }
145a790882dSdrh   memtraceOut = out;
146a790882dSdrh   return rc;
147a790882dSdrh }
148a790882dSdrh 
149a790882dSdrh /* Deactivate memory tracing */
sqlite3MemTraceDeactivate(void)150a790882dSdrh int sqlite3MemTraceDeactivate(void){
151a790882dSdrh   int rc = SQLITE_OK;
152a790882dSdrh   if( memtraceBase.xMalloc!=0 ){
153a790882dSdrh     rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
154a790882dSdrh     if( rc==SQLITE_OK ){
155a790882dSdrh       memset(&memtraceBase, 0, sizeof(memtraceBase));
156a790882dSdrh     }
157a790882dSdrh   }
158a790882dSdrh   memtraceOut = 0;
159a790882dSdrh   return rc;
160a790882dSdrh }
161a790882dSdrh /***** End copy/paste from ext/misc/memtrace.c ***************************/
162a790882dSdrh 
163fb556712Sdrh /*
164fb556712Sdrh ** Progress handler callback
165fb556712Sdrh **
166fb556712Sdrh ** Count the number of callbacks and cause an abort once the limit is
167fb556712Sdrh ** reached.
168fb556712Sdrh */
progress_handler(void * pNotUsed)169fb556712Sdrh static int progress_handler(void *pNotUsed){
170fb556712Sdrh   nCb++;
171fb556712Sdrh   if( nCb<mxCb ) return 0;
172fb556712Sdrh   if( eVerbosity>=1 ){
173fb556712Sdrh     printf("-- Progress limit of %d reached\n", mxCb);
174fb556712Sdrh   }
175fb556712Sdrh   return 1;
176fb556712Sdrh }
177fb556712Sdrh 
178d811d844Sdrh /* libFuzzer invokes this routine with fuzzed database files (in aData).
179d811d844Sdrh ** This routine run SQLite against the malformed database to see if it
180d811d844Sdrh ** can provoke a failure or malfunction.
181d811d844Sdrh */
LLVMFuzzerTestOneInput(const uint8_t * aData,size_t nByte)18265da285eSdrh int LLVMFuzzerTestOneInput(const uint8_t *aData, size_t nByte){
18365da285eSdrh   unsigned char *a;
18465da285eSdrh   sqlite3 *db;
18565da285eSdrh   int rc;
18665da285eSdrh   int i;
187178edcd7Sdrh   sqlite3_int64 x;
18888862d49Sdrh   char *zErr = 0;
18965da285eSdrh 
190d811d844Sdrh   if( eVerbosity>=1 ){
191d811d844Sdrh     printf("************** nByte=%d ***************\n", (int)nByte);
192d811d844Sdrh     fflush(stdout);
193d811d844Sdrh   }
19462a88294Sdrh   if( sqlite3_initialize() ) return 0;
195ad9bfa5eSdrh   rc = sqlite3_open(0, &db);
19665da285eSdrh   if( rc ) return 1;
197ad9bfa5eSdrh   a = sqlite3_malloc64(nByte+1);
19865da285eSdrh   if( a==0 ) return 1;
19965da285eSdrh   memcpy(a, aData, nByte);
20065da285eSdrh   sqlite3_deserialize(db, "main", a, nByte, nByte,
20165da285eSdrh         SQLITE_DESERIALIZE_RESIZEABLE |
20265da285eSdrh         SQLITE_DESERIALIZE_FREEONCLOSE);
203178edcd7Sdrh   x = szMax;
204ddc28c23Sdrh #ifdef SQLITE_FCNTL_SIZE_LIMIT
205178edcd7Sdrh   sqlite3_file_control(db, "main", SQLITE_FCNTL_SIZE_LIMIT, &x);
206ddc28c23Sdrh #endif
2071972c8cfSdrh   if( bVdbeDebug ){
2081972c8cfSdrh     sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
2091972c8cfSdrh   }
210fb556712Sdrh   if( mxCb>0 ){
211fb556712Sdrh     sqlite3_progress_handler(db, 10, progress_handler, 0);
212fb556712Sdrh   }
213e6e96b1bSdrh #ifdef SQLITE_TESTCTRL_PRNG_SEED
2142e6d83bcSdrh   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db);
215e6e96b1bSdrh #endif
21665da285eSdrh   for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){
217d811d844Sdrh     if( eVerbosity>=1 ){
218d811d844Sdrh       printf("%s\n", azSql[i]);
219d811d844Sdrh       fflush(stdout);
220d811d844Sdrh     }
22188862d49Sdrh     zErr = 0;
222fb556712Sdrh     nCb = 0;
22388862d49Sdrh     rc = sqlite3_exec(db, azSql[i], 0, 0, &zErr);
22488862d49Sdrh     if( rc && eVerbosity>=1 ){
22588862d49Sdrh       printf("-- rc=%d zErr=%s\n", rc, zErr);
22688862d49Sdrh     }
22788862d49Sdrh     sqlite3_free(zErr);
22865da285eSdrh   }
229ad9bfa5eSdrh   rc = sqlite3_close(db);
230ad9bfa5eSdrh   if( rc!=SQLITE_OK ){
231ad9bfa5eSdrh     fprintf(stdout, "sqlite3_close() returns %d\n", rc);
232ad9bfa5eSdrh   }
233d811d844Sdrh   if( sqlite3_memory_used()!=0 ){
234ad9bfa5eSdrh     int nAlloc = 0;
235ad9bfa5eSdrh     int nNotUsed = 0;
236ad9bfa5eSdrh     sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
237ad9bfa5eSdrh     fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
238ad9bfa5eSdrh             sqlite3_memory_used(), nAlloc);
239d811d844Sdrh     exit(1);
240d811d844Sdrh   }
241d811d844Sdrh   return 0;
242d811d844Sdrh }
243d811d844Sdrh 
2441972c8cfSdrh /*
2451972c8cfSdrh ** Return the number of "v" characters in a string.  Return 0 if there
2461972c8cfSdrh ** are any characters in the string other than "v".
2471972c8cfSdrh */
numberOfVChar(const char * z)2481972c8cfSdrh static int numberOfVChar(const char *z){
2491972c8cfSdrh   int N = 0;
2501972c8cfSdrh   while( z[0] && z[0]=='v' ){
2511972c8cfSdrh     z++;
2521972c8cfSdrh     N++;
2531972c8cfSdrh   }
2541972c8cfSdrh   return z[0]==0 ? N : 0;
2551972c8cfSdrh }
2561972c8cfSdrh 
257d811d844Sdrh /* libFuzzer invokes this routine once when the executable starts, to
258d811d844Sdrh ** process the command-line arguments.
259d811d844Sdrh */
LLVMFuzzerInitialize(int * pArgc,char *** pArgv)260d811d844Sdrh int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){
2611972c8cfSdrh   int i, j, n;
262d811d844Sdrh   int argc = *pArgc;
263d811d844Sdrh   char **argv = *pArgv;
264d811d844Sdrh   for(i=j=1; i<argc; i++){
265d811d844Sdrh     char *z = argv[i];
266d811d844Sdrh     if( z[0]=='-' ){
267d811d844Sdrh       z++;
268d811d844Sdrh       if( z[0]=='-' ) z++;
2691972c8cfSdrh       if( z[0]=='v' && (n = numberOfVChar(z))>0 ){
2701972c8cfSdrh         eVerbosity += n;
2711972c8cfSdrh         continue;
2721972c8cfSdrh       }
2731972c8cfSdrh       if( strcmp(z,"vdbe-debug")==0 ){
2741972c8cfSdrh         bVdbeDebug = 1;
275d811d844Sdrh         continue;
276d811d844Sdrh       }
277fb556712Sdrh       if( strcmp(z,"limit")==0 ){
278fb556712Sdrh         if( i+1==argc ){
279fb556712Sdrh           fprintf(stderr, "missing argument to %s\n", argv[i]);
280fb556712Sdrh           exit(1);
281fb556712Sdrh         }
282fb556712Sdrh         mxCb = strtol(argv[++i], 0, 0);
283fb556712Sdrh         continue;
284fb556712Sdrh       }
285a790882dSdrh       if( strcmp(z,"memtrace")==0 ){
286a790882dSdrh         sqlite3MemTraceActivate(stdout);
287a790882dSdrh         continue;
288a790882dSdrh       }
289178edcd7Sdrh       if( strcmp(z,"max-db-size")==0 ){
290178edcd7Sdrh         if( i+1==argc ){
291178edcd7Sdrh           fprintf(stderr, "missing argument to %s\n", argv[i]);
292178edcd7Sdrh           exit(1);
293178edcd7Sdrh         }
294178edcd7Sdrh         szMax = strtol(argv[++i], 0, 0);
295178edcd7Sdrh         continue;
296178edcd7Sdrh       }
297f461bab2Sdrh       if( strcmp(z, "lookaside")==0 ){
298f461bab2Sdrh         int sz, nSlot;
299f461bab2Sdrh         if( i+2>=argc ){
300f461bab2Sdrh           fprintf(stderr,
301f461bab2Sdrh              "--lookaside requires two arguments: slot-size num-slots\n");
302f461bab2Sdrh           exit(1);
303f461bab2Sdrh         }
304f461bab2Sdrh         sz = atoi(argv[++i]);
305f461bab2Sdrh         nSlot = atoi(argv[++i]);
306f461bab2Sdrh         sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, nSlot);
307f461bab2Sdrh         continue;
308f461bab2Sdrh       }
3097e85e903Sdrh #ifndef _WIN32
3105976552aSdrh       if( strcmp(z,"max-stack")==0
3115976552aSdrh        || strcmp(z,"max-data")==0
3125976552aSdrh        || strcmp(z,"max-as")==0
3135976552aSdrh       ){
3148ed07d12Sdrh         struct rlimit x,y;
3155976552aSdrh         int resource = RLIMIT_STACK;
3165976552aSdrh         char *zType = "RLIMIT_STACK";
3178ed07d12Sdrh         if( i+1==argc ){
3188ed07d12Sdrh           fprintf(stderr, "missing argument to %s\n", argv[i]);
3198ed07d12Sdrh           exit(1);
3208ed07d12Sdrh         }
3215976552aSdrh         if( z[4]=='d' ){
3225976552aSdrh           resource = RLIMIT_DATA;
3235976552aSdrh           zType = "RLIMIT_DATA";
3245976552aSdrh         }
3255976552aSdrh         if( z[4]=='a' ){
3265976552aSdrh           resource = RLIMIT_AS;
3275976552aSdrh           zType = "RLIMIT_AS";
3285976552aSdrh         }
3298ed07d12Sdrh         memset(&x,0,sizeof(x));
3305976552aSdrh         getrlimit(resource, &x);
3318ed07d12Sdrh         y.rlim_cur = atoi(argv[++i]);
3328ed07d12Sdrh         y.rlim_max = x.rlim_cur;
3335976552aSdrh         setrlimit(resource, &y);
3348ed07d12Sdrh         memset(&y,0,sizeof(y));
3355976552aSdrh         getrlimit(resource, &y);
3365976552aSdrh         printf("%s changed from %d to %d\n",
3375976552aSdrh                zType, (int)x.rlim_cur, (int)y.rlim_cur);
3388ed07d12Sdrh         continue;
3398ed07d12Sdrh       }
3407e85e903Sdrh #endif /* _WIN32 */
341d811d844Sdrh     }
342b10a50e7Sdrh     argv[j++] = argv[i];
343d811d844Sdrh   }
344b10a50e7Sdrh   argv[j] = 0;
345d811d844Sdrh   *pArgc = j;
34665da285eSdrh   return 0;
34765da285eSdrh }
348e65b9c6aSdrh 
349e65b9c6aSdrh #ifdef STANDALONE
350e65b9c6aSdrh /*
351e65b9c6aSdrh ** Read an entire file into memory.  Space to hold the file comes
352e65b9c6aSdrh ** from malloc().
353e65b9c6aSdrh */
readFile(const char * zName,int * pnByte)354e65b9c6aSdrh static unsigned char *readFile(const char *zName, int *pnByte){
355e65b9c6aSdrh   FILE *in = fopen(zName, "rb");
356e65b9c6aSdrh   long nIn;
357e65b9c6aSdrh   size_t nRead;
358e65b9c6aSdrh   unsigned char *pBuf;
359e65b9c6aSdrh   if( in==0 ) return 0;
360e65b9c6aSdrh   fseek(in, 0, SEEK_END);
361e65b9c6aSdrh   nIn = ftell(in);
362e65b9c6aSdrh   rewind(in);
363e65b9c6aSdrh   pBuf = malloc( nIn+1 );
364e65b9c6aSdrh   if( pBuf==0 ){ fclose(in); return 0; }
365e65b9c6aSdrh   nRead = fread(pBuf, nIn, 1, in);
366e65b9c6aSdrh   fclose(in);
367e65b9c6aSdrh   if( nRead!=1 ){
368e65b9c6aSdrh     free(pBuf);
369e65b9c6aSdrh     return 0;
370e65b9c6aSdrh   }
371e65b9c6aSdrh   pBuf[nIn] = 0;
372e65b9c6aSdrh   if( pnByte ) *pnByte = nIn;
373e65b9c6aSdrh   return pBuf;
374e65b9c6aSdrh }
375e65b9c6aSdrh #endif /* STANDALONE */
376e65b9c6aSdrh 
377e65b9c6aSdrh #ifdef STANDALONE
main(int argc,char ** argv)378e65b9c6aSdrh int main(int argc, char **argv){
379e65b9c6aSdrh   int i;
380e65b9c6aSdrh   LLVMFuzzerInitialize(&argc, &argv);
381e65b9c6aSdrh   for(i=1; i<argc; i++){
382e65b9c6aSdrh     unsigned char *pIn;
383e65b9c6aSdrh     int nIn;
384e65b9c6aSdrh     pIn = readFile(argv[i], &nIn);
385e65b9c6aSdrh     if( pIn ){
386e65b9c6aSdrh       LLVMFuzzerTestOneInput((const uint8_t*)pIn, (size_t)nIn);
387e65b9c6aSdrh       free(pIn);
388e65b9c6aSdrh     }
389e65b9c6aSdrh   }
3900ba32347Sdrh #ifdef RUSAGE_SELF
391b10a50e7Sdrh   if( eVerbosity>0 ){
3925976552aSdrh     struct rusage x;
393b10a50e7Sdrh     printf("SQLite %s\n", sqlite3_sourceid());
3945976552aSdrh     memset(&x, 0, sizeof(x));
3955976552aSdrh     if( getrusage(RUSAGE_SELF, &x)==0 ){
3965976552aSdrh       printf("Maximum RSS = %ld KB\n", x.ru_maxrss);
3975976552aSdrh     }
398b10a50e7Sdrh   }
3990ba32347Sdrh #endif
400e65b9c6aSdrh   return 0;
401e65b9c6aSdrh }
402e65b9c6aSdrh #endif /*STANDALONE*/
403