1ea432ba2Sdrh /* 2ea432ba2Sdrh ** This module interfaces SQLite to the Google OSS-Fuzz, fuzzer as a service. 3ea432ba2Sdrh ** (https://github.com/google/oss-fuzz) 4ea432ba2Sdrh */ 5ea432ba2Sdrh #include <stddef.h> 6ea432ba2Sdrh #include <stdint.h> 7ea432ba2Sdrh #include "sqlite3.h" 8ea432ba2Sdrh 9a6bf20b5Sdrh /* Return the current real-world time in milliseconds since the 10a6bf20b5Sdrh ** Julian epoch (-4714-11-24). 11a6bf20b5Sdrh */ 12a6bf20b5Sdrh static sqlite3_int64 timeOfDay(void){ 13a6bf20b5Sdrh static sqlite3_vfs *clockVfs = 0; 14a6bf20b5Sdrh sqlite3_int64 t; 15a6bf20b5Sdrh if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); 16a6bf20b5Sdrh if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ 17a6bf20b5Sdrh clockVfs->xCurrentTimeInt64(clockVfs, &t); 18a6bf20b5Sdrh }else{ 19a6bf20b5Sdrh double r; 20a6bf20b5Sdrh clockVfs->xCurrentTime(clockVfs, &r); 21a6bf20b5Sdrh t = (sqlite3_int64)(r*86400000.0); 22a6bf20b5Sdrh } 23a6bf20b5Sdrh return t; 24a6bf20b5Sdrh } 25a6bf20b5Sdrh 26e6ce2b67Sdrh #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 27ea432ba2Sdrh /* 28a6bf20b5Sdrh ** Progress handler callback. 29a6bf20b5Sdrh ** 30a6bf20b5Sdrh ** The argument is the cutoff-time after which all processing should 31a6bf20b5Sdrh ** stop. So return non-zero if the cut-off time is exceeded. 32ea432ba2Sdrh */ 33ea432ba2Sdrh static int progress_handler(void *pReturn) { 34a6bf20b5Sdrh sqlite3_int64 iCutoffTime = *(sqlite3_int64*)pReturn; 35a6bf20b5Sdrh return timeOfDay()>=iCutoffTime; 36ea432ba2Sdrh } 37e6ce2b67Sdrh #endif 38ea432ba2Sdrh 39ea432ba2Sdrh /* 40ea432ba2Sdrh ** Callback for sqlite3_exec(). 41ea432ba2Sdrh */ 42ea432ba2Sdrh static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ 43ea432ba2Sdrh int i; 4455377b47Sdrh if( argv ){ 45ea432ba2Sdrh for(i=0; i<argc; i++) sqlite3_free(sqlite3_mprintf("%s", argv[i])); 4655377b47Sdrh } 47ea432ba2Sdrh return ((*(int*)pCnt)--)<=0; 48ea432ba2Sdrh } 49ea432ba2Sdrh 50ea432ba2Sdrh /* 51ea432ba2Sdrh ** Main entry point. The fuzzer invokes this function with each 52ea432ba2Sdrh ** fuzzed input. 53ea432ba2Sdrh */ 54ea432ba2Sdrh int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 55ea432ba2Sdrh int execCnt = 0; /* Abort row callback when count reaches zero */ 56ea432ba2Sdrh char *zErrMsg = 0; /* Error message returned by sqlite_exec() */ 57ea432ba2Sdrh sqlite3 *db; /* The database connection */ 58ea432ba2Sdrh uint8_t uSelector; /* First byte of input data[] */ 59ea432ba2Sdrh int rc; /* Return code from various interfaces */ 60ea432ba2Sdrh char *zSql; /* Zero-terminated copy of data[] */ 61a6bf20b5Sdrh sqlite3_int64 iCutoff; /* Cutoff timer */ 62ea432ba2Sdrh 63ea432ba2Sdrh if( size<3 ) return 0; /* Early out if unsufficient data */ 64ea432ba2Sdrh 65ea432ba2Sdrh /* Extract the selector byte from the beginning of the input. But only 66ea432ba2Sdrh ** do this if the second byte is a \n. If the second byte is not \n, 67ea432ba2Sdrh ** then use a default selector */ 68ea432ba2Sdrh if( data[1]=='\n' ){ 69ea432ba2Sdrh uSelector = data[0]; data += 2; size -= 2; 70ea432ba2Sdrh }else{ 71ea432ba2Sdrh uSelector = 0xfd; 72ea432ba2Sdrh } 73ea432ba2Sdrh 74ea432ba2Sdrh /* Open the database connection. Only use an in-memory database. */ 75ea432ba2Sdrh rc = sqlite3_open_v2("fuzz.db", &db, 76ea432ba2Sdrh SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); 77ea432ba2Sdrh if( rc ) return 0; 78ea432ba2Sdrh 79e6ce2b67Sdrh #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 80*bbc01774Sdrh /* Invoke the progress handler frequently to check to see if we 81*bbc01774Sdrh ** are taking too long. The progress handler will return true 82*bbc01774Sdrh ** (which will block further processing) if more than 10 seconds have 83*bbc01774Sdrh ** elapsed since the start of the test. 84a6bf20b5Sdrh */ 85a6bf20b5Sdrh iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */ 86*bbc01774Sdrh sqlite3_progress_handler(db, 10, progress_handler, (void*)&iCutoff); 87e6ce2b67Sdrh #endif 88ea432ba2Sdrh 89a6bf20b5Sdrh /* Bit 1 of the selector enables foreign key constraints */ 90ea432ba2Sdrh sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); 91ea432ba2Sdrh uSelector >>= 1; 92ea432ba2Sdrh 93ea432ba2Sdrh /* Remaining bits of the selector determine a limit on the number of 94ea432ba2Sdrh ** output rows */ 95ea432ba2Sdrh execCnt = uSelector + 1; 96ea432ba2Sdrh 97ea432ba2Sdrh /* Run the SQL. The sqlite_exec() interface expects a zero-terminated 98ea432ba2Sdrh ** string, so make a copy. */ 99ea432ba2Sdrh zSql = sqlite3_mprintf("%.*s", (int)size, data); 100ea432ba2Sdrh sqlite3_exec(db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); 101ea432ba2Sdrh 102ea432ba2Sdrh /* Cleanup and return */ 103ea432ba2Sdrh sqlite3_free(zErrMsg); 104ea432ba2Sdrh sqlite3_free(zSql); 105ea432ba2Sdrh sqlite3_close(db); 106ea432ba2Sdrh return 0; 107ea432ba2Sdrh } 108