When fuzzing sqlite with American Fuzzy Lop, I believe I found the
following bug in the sqlite shell:

In shell.c:2563-2571 (in the amalgamated version), in the function
shell_dbinfo_command:

1. pFile is declared (2563): sqlite3_file *pFile;
2. Its address is passed to sqlite3_file_control
(2570): sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
3. pFile is checked to see if it is equal to NULL, and if not, it is
dereferenced (2571): if( pFile==0 || pFile->pMethods==0 ||
pFile->pMethods->xRead==0 ){

When I input the following commands into the sqlite shell:

create table t1(one small);
.d table

sqlite3_file_control() does not set pFile, so pFile remains unitialized
after the function returns.
By my understanding, this behavior is safe only if pFile is initialized to
0, which is not always the case.

When I compiled sqlite (with the following options, using either gcc or
clang: "shell.c sqlite3.c -lpthread -ldl -o sqlite3") with glibc 2.6.18,
pFile is initialized to 0x7ffff7df18f5 (it is some other nonzero value with
clang). As a result, given the input I mentioned above, the program will
dereference pFile on line 2571 and segfault. On later versions of glibc I
have found that this bug does not always present itself (since pFile
happens to be initialized to 0) but I have also reproduced this segfault
with glibc 2.6.32 (again, using the amalgated source from the main download
page and the instructions provided on how to compile it).

If your compiler fails to produce a binary vulnerable to this bug, you can
(probably) use the -fsanitize=memory flag that clang supports or the
-fsanitize=address flag that both clang and gcc support to reproduce the
crash.

I believe explicitly initializing pFile like so:

sqlite3_file *pFile = NULL;

Would fix this problem.

Thank you,
Jonathan Metzman

Reply via email to