4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
13 ** This program is designed for fuzz-testing SQLite database files using
14 ** the -fsanitize=fuzzer option of clang.
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.
21 ** For best results the seed database files should have these tables:
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.
28 ** Any of these tables can be virtual tables, for example FTS or RTree tables.
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
48 #include <sys/resource.h>
53 ** This is the is the SQL that is run against the database.
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);",
68 /* Output verbosity level. 0 means complete silence */
71 /* True to activate PRAGMA vdbe_debug=on */
72 static int bVdbeDebug
= 0;
74 /* Maximum size of the in-memory database file */
75 static sqlite3_int64 szMax
= 104857600;
77 /* Progress handler callback data */
78 static int nCb
= 0; /* Number of callbacks seen so far */
79 static int mxCb
= 250000; /* Maximum allowed callbacks */
81 /***** Copy/paste from ext/misc/memtrace.c ***************************/
82 /* The original memory allocation routines */
83 static sqlite3_mem_methods memtraceBase
;
84 static FILE *memtraceOut
;
86 /* Methods that trace memory allocations */
87 static void *memtraceMalloc(int n
){
89 fprintf(memtraceOut
, "MEMTRACE: allocate %d bytes\n",
90 memtraceBase
.xRoundup(n
));
92 return memtraceBase
.xMalloc(n
);
94 static void memtraceFree(void *p
){
97 fprintf(memtraceOut
, "MEMTRACE: free %d bytes\n", memtraceBase
.xSize(p
));
99 memtraceBase
.xFree(p
);
101 static void *memtraceRealloc(void *p
, int n
){
102 if( p
==0 ) return memtraceMalloc(n
);
108 fprintf(memtraceOut
, "MEMTRACE: resize %d -> %d bytes\n",
109 memtraceBase
.xSize(p
), memtraceBase
.xRoundup(n
));
111 return memtraceBase
.xRealloc(p
, n
);
113 static int memtraceSize(void *p
){
114 return memtraceBase
.xSize(p
);
116 static int memtraceRoundup(int n
){
117 return memtraceBase
.xRoundup(n
);
119 static int memtraceInit(void *p
){
120 return memtraceBase
.xInit(p
);
122 static void memtraceShutdown(void *p
){
123 memtraceBase
.xShutdown(p
);
126 /* The substitute memory allocator */
127 static sqlite3_mem_methods ersaztMethods
= {
137 /* Begin tracing memory allocations to out. */
138 int sqlite3MemTraceActivate(FILE *out
){
140 if( memtraceBase
.xMalloc
==0 ){
141 rc
= sqlite3_config(SQLITE_CONFIG_GETMALLOC
, &memtraceBase
);
143 rc
= sqlite3_config(SQLITE_CONFIG_MALLOC
, &ersaztMethods
);
150 /* Deactivate memory tracing */
151 int sqlite3MemTraceDeactivate(void){
153 if( memtraceBase
.xMalloc
!=0 ){
154 rc
= sqlite3_config(SQLITE_CONFIG_MALLOC
, &memtraceBase
);
156 memset(&memtraceBase
, 0, sizeof(memtraceBase
));
162 /***** End copy/paste from ext/misc/memtrace.c ***************************/
165 ** Progress handler callback
167 ** Count the number of callbacks and cause an abort once the limit is
170 static int progress_handler(void *pNotUsed
){
172 if( nCb
<mxCb
) return 0;
174 printf("-- Progress limit of %d reached\n", mxCb
);
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.
183 int LLVMFuzzerTestOneInput(const uint8_t *aData
, size_t nByte
){
192 printf("************** nByte=%d ***************\n", (int)nByte
);
195 if( sqlite3_initialize() ) return 0;
196 rc
= sqlite3_open(0, &db
);
198 a
= sqlite3_malloc64(nByte
+1);
200 memcpy(a
, aData
, nByte
);
201 sqlite3_deserialize(db
, "main", a
, nByte
, nByte
,
202 SQLITE_DESERIALIZE_RESIZEABLE
|
203 SQLITE_DESERIALIZE_FREEONCLOSE
);
205 #ifdef SQLITE_FCNTL_SIZE_LIMIT
206 sqlite3_file_control(db
, "main", SQLITE_FCNTL_SIZE_LIMIT
, &x
);
209 sqlite3_exec(db
, "PRAGMA vdbe_debug=ON", 0, 0, 0);
212 sqlite3_progress_handler(db
, 10, progress_handler
, 0);
214 #ifdef SQLITE_TESTCTRL_PRNG_SEED
215 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED
, 1, db
);
217 for(i
=0; i
<sizeof(azSql
)/sizeof(azSql
[0]); i
++){
219 printf("%s\n", azSql
[i
]);
224 rc
= sqlite3_exec(db
, azSql
[i
], 0, 0, &zErr
);
225 if( rc
&& eVerbosity
>=1 ){
226 printf("-- rc=%d zErr=%s\n", rc
, zErr
);
230 rc
= sqlite3_close(db
);
232 fprintf(stdout
, "sqlite3_close() returns %d\n", rc
);
234 if( sqlite3_memory_used()!=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
);
246 ** Return the number of "v" characters in a string. Return 0 if there
247 ** are any characters in the string other than "v".
249 static int numberOfVChar(const char *z
){
251 while( z
[0] && z
[0]=='v' ){
255 return z
[0]==0 ? N
: 0;
258 /* libFuzzer invokes this routine once when the executable starts, to
259 ** process the command-line arguments.
261 int LLVMFuzzerInitialize(int *pArgc
, char ***pArgv
){
264 char **argv
= *pArgv
;
265 for(i
=j
=1; i
<argc
; i
++){
270 if( z
[0]=='v' && (n
= numberOfVChar(z
))>0 ){
274 if( strcmp(z
,"vdbe-debug")==0 ){
278 if( strcmp(z
,"limit")==0 ){
280 fprintf(stderr
, "missing argument to %s\n", argv
[i
]);
283 mxCb
= strtol(argv
[++i
], 0, 0);
286 if( strcmp(z
,"memtrace")==0 ){
287 sqlite3MemTraceActivate(stdout
);
290 if( strcmp(z
,"mem")==0 ){
294 if( strcmp(z
,"max-db-size")==0 ){
296 fprintf(stderr
, "missing argument to %s\n", argv
[i
]);
299 szMax
= strtol(argv
[++i
], 0, 0);
303 if( strcmp(z
,"max-stack")==0
304 || strcmp(z
,"max-data")==0
305 || strcmp(z
,"max-as")==0
308 int resource
= RLIMIT_STACK
;
309 char *zType
= "RLIMIT_STACK";
311 fprintf(stderr
, "missing argument to %s\n", argv
[i
]);
315 resource
= RLIMIT_DATA
;
316 zType
= "RLIMIT_DATA";
319 resource
= RLIMIT_AS
;
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
);
344 ** Read an entire file into memory. Space to hold the file comes
347 static unsigned char *readFile(const char *zName
, int *pnByte
){
348 FILE *in
= fopen(zName
, "rb");
352 if( in
==0 ) return 0;
353 fseek(in
, 0, SEEK_END
);
356 pBuf
= malloc( nIn
+1 );
357 if( pBuf
==0 ){ fclose(in
); return 0; }
358 nRead
= fread(pBuf
, nIn
, 1, in
);
365 if( pnByte
) *pnByte
= nIn
;
368 #endif /* STANDALONE */
371 int main(int argc
, char **argv
){
373 LLVMFuzzerInitialize(&argc
, &argv
);
374 for(i
=1; i
<argc
; i
++){
377 pIn
= readFile(argv
[i
], &nIn
);
379 LLVMFuzzerTestOneInput((const uint8_t*)pIn
, (size_t)nIn
);
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
);
395 #endif /*STANDALONE*/