Re: [sqlite] FTS5 Transaction Leads to OOB Read
YES. AFL with ASAN. ___ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] FTS5 Transaction Leads to OOB Read
That's the error I got too. Now fixed here: https://sqlite.org/src/info/b3fa58dd7403dbd4 Dan. On 19/3/62 04:22, Dominique Pellé wrote: Chu wrote: The code: ``` CREATE VIRTUAL TABLE t1 USING fts5(content); BEGIN; INSERT INTO t1 (content) VALUES(''); SELECT * FROM t1('*'); END; ``` As you can see, it creates a virtual table with fts5, and run a transaction on it, this will leads to a OOB READ. The ASAN report: ``` ➜ sqlite-crashes ../sqlite-autoconf-3270200/sqlite3 < 2-oob-read.sql = ==21007==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60d02898 at pc 0x7f0cad16e6a3 bp 0x7ffdc88ddc80 sp 0x7ffdc88dd430 READ of size 81 at 0x60d02898 thread T0 #0 0x7f0cad16e6a2 (/lib/x86_64-linux-gnu/libasan.so.5+0xb86a2) #1 0x563324ca4013 in fts5HashEntrySort /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207762 #2 0x563324e685f9 in sqlite3Fts5HashScanInit /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207820 #3 0x563324e685f9 in fts5SegIterHashInit /root/Documents/sqlite-autoconf-3270200/sqlite3.c:210321 ...snip.. Just to confirm that there is a bug when running your queries in the SQLite-3.27.2 shell with valgrind. I did not get a heap overflow, but valgrind complains about uninitialized memory in the same fts5HashEntrySort function as in your stack: $ valgrind --track-origins=yes --num-callers=50 sqlite3_shell ==10856== Memcheck, a memory error detector ==10856== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==10856== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==10856== Command: ./Output/Binary/x86_64-Linux-clang/Debug/bin/sqlite3_shell ==10856== SQLite version 3.27.2 2019-02-25 16:06:06 NDSeV devkit 3.27.2.1 2019-02-26 16:04:39 990c4f90c3340db5 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> CREATE VIRTUAL TABLE t1 USING fts5(content); sqlite> BEGIN; sqlite> INSERT INTO t1 (content) VALUES(''); sqlite> SELECT * FROM t1('*'); ==10856== Conditional jump or move depends on uninitialised value(s) ==10856==at 0x4C362B2: __memcmp_sse4_1 (vg_replace_strmem.c:) ==10856==by 0x4ECC86: fts5HashEntrySort (nds_sqlite3.c:207811) ==10856==by 0x4EC55D: sqlite3Fts5HashScanInit (nds_sqlite3.c:207869) ==10856==by 0x4EBB45: fts5SegIterHashInit (nds_sqlite3.c:210370) ==10856==by 0x4EB1BE: fts5MultiIterNew (nds_sqlite3.c:211319) ==10856==by 0x4EB5A8: fts5SetupPrefixIter (nds_sqlite3.c:212995) ==10856==by 0x4EAE4A: sqlite3Fts5IndexQuery (nds_sqlite3.c:213324) ==10856==by 0x4EAA61: fts5ExprNearInitAll (nds_sqlite3.c:205310) ==10856==by 0x4EA6F3: fts5ExprNodeFirst (nds_sqlite3.c:205827) ==10856==by 0x4EA5B4: sqlite3Fts5ExprFirst (nds_sqlite3.c:205885) ==10856==by 0x4E9D1A: fts5CursorFirst (nds_sqlite3.c:215420) ==10856==by 0x4E2DD3: fts5FilterMethod (nds_sqlite3.c:215702) ==10856==by 0x4672A7: sqlite3VdbeExec (nds_sqlite3.c:90382) ==10856==by 0x42F876: sqlite3Step (nds_sqlite3.c:81765) ==10856==by 0x42F51C: sqlite3_step (nds_sqlite3.c:81830) ==10856==by 0x4236B8: exec_prepared_stmt (shell.c:10469) ==10856==by 0x4104EB: shell_exec (shell.c:10776) ==10856==by 0x42414E: runOneSqlLine (shell.c:16136) ==10856==by 0x410C5A: process_input (shell.c:16236) ==10856==by 0x40752D: main (shell.c:16995) ==10856== Uninitialised value was created by a heap allocation ==10856==at 0x4C2FE56: malloc (vg_replace_malloc.c:299) ==10856==by 0x4E0098: sqlite3MemMalloc (nds_sqlite3.c:22886) ==10856==by 0x441ED0: mallocWithAlarm (nds_sqlite3.c:26718) ==10856==by 0x425E0B: sqlite3Malloc (nds_sqlite3.c:26748) ==10856==by 0x425E7F: sqlite3_malloc64 (nds_sqlite3.c:26772) ==10856==by 0x4FE464: sqlite3Fts5HashWrite (nds_sqlite3.c:207636) ==10856==by 0x4FE1F0: sqlite3Fts5IndexWrite (nds_sqlite3.c:213247) ==10856==by 0x4FACB9: fts5StorageInsertCallback (nds_sqlite3.c:217629) ==10856==by 0x505B04: fts5UnicodeTokenize (nds_sqlite3.c:218923) ==10856==by 0x4F623D: sqlite3Fts5Tokenize (nds_sqlite3.c:204268) ==10856==by 0x4FA0DD: sqlite3Fts5StorageIndexInsert (nds_sqlite3.c:217984) ==10856==by 0x4F9E44: fts5StorageInsert (nds_sqlite3.c:215929) ==10856==by 0x4E359D: fts5UpdateMethod (nds_sqlite3.c:216036) ==10856==by 0x4677E6: sqlite3VdbeExec (nds_sqlite3.c:90593) ==10856==by 0x42F876: sqlite3Step (nds_sqlite3.c:81765) ==10856==by 0x42F51C: sqlite3_step (nds_sqlite3.c:81830) ==10856==by 0x4236B8: exec_prepared_stmt (shell.c:10469) ==10856==by 0x4104EB: shell_exec (shell.c:10776) ==10856==by 0x42414E: runOneSqlLine (shell.c:16136) ==10856==by 0x410C5A:
Re: [sqlite] FTS5 Transaction Leads to OOB Read
Chu wrote: > The code: > > ``` > CREATE VIRTUAL TABLE t1 USING fts5(content); > > BEGIN; > INSERT INTO t1 (content) VALUES(''); > SELECT * FROM > t1('*'); > END; > ``` > > As you can see, it creates a virtual table with fts5, and run a transaction > on it, this will leads to a OOB READ. The ASAN report: > > ``` > ➜ sqlite-crashes ../sqlite-autoconf-3270200/sqlite3 < 2-oob-read.sql > = > ==21007==ERROR: AddressSanitizer: heap-buffer-overflow on address > 0x60d02898 at pc 0x7f0cad16e6a3 bp 0x7ffdc88ddc80 sp 0x7ffdc88dd430 > READ of size 81 at 0x60d02898 thread T0 > #0 0x7f0cad16e6a2 (/lib/x86_64-linux-gnu/libasan.so.5+0xb86a2) > #1 0x563324ca4013 in fts5HashEntrySort > /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207762 > #2 0x563324e685f9 in sqlite3Fts5HashScanInit > /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207820 > #3 0x563324e685f9 in fts5SegIterHashInit > /root/Documents/sqlite-autoconf-3270200/sqlite3.c:210321 ...snip.. Just to confirm that there is a bug when running your queries in the SQLite-3.27.2 shell with valgrind. I did not get a heap overflow, but valgrind complains about uninitialized memory in the same fts5HashEntrySort function as in your stack: $ valgrind --track-origins=yes --num-callers=50 sqlite3_shell ==10856== Memcheck, a memory error detector ==10856== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==10856== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==10856== Command: ./Output/Binary/x86_64-Linux-clang/Debug/bin/sqlite3_shell ==10856== SQLite version 3.27.2 2019-02-25 16:06:06 NDSeV devkit 3.27.2.1 2019-02-26 16:04:39 990c4f90c3340db5 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> CREATE VIRTUAL TABLE t1 USING fts5(content); sqlite> BEGIN; sqlite> INSERT INTO t1 (content) VALUES(''); sqlite> SELECT * FROM t1('*'); ==10856== Conditional jump or move depends on uninitialised value(s) ==10856==at 0x4C362B2: __memcmp_sse4_1 (vg_replace_strmem.c:) ==10856==by 0x4ECC86: fts5HashEntrySort (nds_sqlite3.c:207811) ==10856==by 0x4EC55D: sqlite3Fts5HashScanInit (nds_sqlite3.c:207869) ==10856==by 0x4EBB45: fts5SegIterHashInit (nds_sqlite3.c:210370) ==10856==by 0x4EB1BE: fts5MultiIterNew (nds_sqlite3.c:211319) ==10856==by 0x4EB5A8: fts5SetupPrefixIter (nds_sqlite3.c:212995) ==10856==by 0x4EAE4A: sqlite3Fts5IndexQuery (nds_sqlite3.c:213324) ==10856==by 0x4EAA61: fts5ExprNearInitAll (nds_sqlite3.c:205310) ==10856==by 0x4EA6F3: fts5ExprNodeFirst (nds_sqlite3.c:205827) ==10856==by 0x4EA5B4: sqlite3Fts5ExprFirst (nds_sqlite3.c:205885) ==10856==by 0x4E9D1A: fts5CursorFirst (nds_sqlite3.c:215420) ==10856==by 0x4E2DD3: fts5FilterMethod (nds_sqlite3.c:215702) ==10856==by 0x4672A7: sqlite3VdbeExec (nds_sqlite3.c:90382) ==10856==by 0x42F876: sqlite3Step (nds_sqlite3.c:81765) ==10856==by 0x42F51C: sqlite3_step (nds_sqlite3.c:81830) ==10856==by 0x4236B8: exec_prepared_stmt (shell.c:10469) ==10856==by 0x4104EB: shell_exec (shell.c:10776) ==10856==by 0x42414E: runOneSqlLine (shell.c:16136) ==10856==by 0x410C5A: process_input (shell.c:16236) ==10856==by 0x40752D: main (shell.c:16995) ==10856== Uninitialised value was created by a heap allocation ==10856==at 0x4C2FE56: malloc (vg_replace_malloc.c:299) ==10856==by 0x4E0098: sqlite3MemMalloc (nds_sqlite3.c:22886) ==10856==by 0x441ED0: mallocWithAlarm (nds_sqlite3.c:26718) ==10856==by 0x425E0B: sqlite3Malloc (nds_sqlite3.c:26748) ==10856==by 0x425E7F: sqlite3_malloc64 (nds_sqlite3.c:26772) ==10856==by 0x4FE464: sqlite3Fts5HashWrite (nds_sqlite3.c:207636) ==10856==by 0x4FE1F0: sqlite3Fts5IndexWrite (nds_sqlite3.c:213247) ==10856==by 0x4FACB9: fts5StorageInsertCallback (nds_sqlite3.c:217629) ==10856==by 0x505B04: fts5UnicodeTokenize (nds_sqlite3.c:218923) ==10856==by 0x4F623D: sqlite3Fts5Tokenize (nds_sqlite3.c:204268) ==10856==by 0x4FA0DD: sqlite3Fts5StorageIndexInsert (nds_sqlite3.c:217984) ==10856==by 0x4F9E44: fts5StorageInsert (nds_sqlite3.c:215929) ==10856==by 0x4E359D: fts5UpdateMethod (nds_sqlite3.c:216036) ==10856==by 0x4677E6: sqlite3VdbeExec (nds_sqlite3.c:90593) ==10856==by 0x42F876: sqlite3Step (nds_sqlite3.c:81765) ==10856==by 0x42F51C: sqlite3_step (nds_sqlite3.c:81830) ==10856==by 0x4236B8: exec_prepared_stmt (shell.c:10469) ==10856==by 0x4104EB: shell_exec (shell.c:10776) ==10856==by 0x42414E: runOneSqlLine (shell.c:16136) ==10856==by 0x410C5A: process_input (shell.c:16236) ==10856==by 0x40752D: main (shell.c:16995) ==10856== sqlite> END; Out
[sqlite] FTS5 Transaction Leads to OOB Read
The code: ``` CREATE VIRTUAL TABLE t1 USING fts5(content); BEGIN; INSERT INTO t1 (content) VALUES(''); SELECT * FROM t1('*'); END; ``` As you can see, it creates a virtual table with fts5, and run a transaction on it, this will leads to a OOB READ. The ASAN report: ``` ➜ sqlite-crashes ../sqlite-autoconf-3270200/sqlite3 < 2-oob-read.sql = ==21007==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60d02898 at pc 0x7f0cad16e6a3 bp 0x7ffdc88ddc80 sp 0x7ffdc88dd430 READ of size 81 at 0x60d02898 thread T0 #0 0x7f0cad16e6a2 (/lib/x86_64-linux-gnu/libasan.so.5+0xb86a2) #1 0x563324ca4013 in fts5HashEntrySort /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207762 #2 0x563324e685f9 in sqlite3Fts5HashScanInit /root/Documents/sqlite-autoconf-3270200/sqlite3.c:207820 #3 0x563324e685f9 in fts5SegIterHashInit /root/Documents/sqlite-autoconf-3270200/sqlite3.c:210321 #4 0x563324e685f9 in fts5MultiIterNew /root/Documents/sqlite-autoconf-3270200/sqlite3.c:211270 #5 0x563324e6b380 in fts5SetupPrefixIter /root/Documents/sqlite-autoconf-3270200/sqlite3.c:212946 #6 0x563324e6b380 in sqlite3Fts5IndexQuery /root/Documents/sqlite-autoconf-3270200/sqlite3.c:213275 #7 0x563324eae566 in fts5ExprNearInitAll /root/Documents/sqlite-autoconf-3270200/sqlite3.c:205261 #8 0x563324eae566 in fts5ExprNodeFirst /root/Documents/sqlite-autoconf-3270200/sqlite3.c:205778 #9 0x563324eaed3d in sqlite3Fts5ExprFirst /root/Documents/sqlite-autoconf-3270200/sqlite3.c:205836 #10 0x563324eaef0d in fts5CursorFirst /root/Documents/sqlite-autoconf-3270200/sqlite3.c:215371 #11 0x563324eb0c9d in fts5FilterMethod /root/Documents/sqlite-autoconf-3270200/sqlite3.c:215653 #12 0x563324dcd73a in sqlite3VdbeExec /root/Documents/sqlite-autoconf-3270200/sqlite3.c:90333 #13 0x563324de9439 in sqlite3Step /root/Documents/sqlite-autoconf-3270200/sqlite3.c:81716 #14 0x563324de9439 in sqlite3_step /root/Documents/sqlite-autoconf-3270200/sqlite3.c:81781 #15 0x563324c1d662 in exec_prepared_stmt /root/Documents/sqlite-autoconf-3270200/shell.c:10445 #16 0x563324c1d662 in shell_exec /root/Documents/sqlite-autoconf-3270200/shell.c:10752 #17 0x563324c1fdf3 in runOneSqlLine /root/Documents/sqlite-autoconf-3270200/shell.c:16106 #18 0x563324c2f466 in process_input /root/Documents/sqlite-autoconf-3270200/shell.c:16206 #19 0x563324bfac98 in main /root/Documents/sqlite-autoconf-3270200/shell.c:16967 #20 0x7f0cacd7009a in __libc_start_main ../csu/libc-start.c:308 #21 0x563324bfc599 in _start (/root/Documents/sqlite-autoconf-3270200/sqlite3+0x46599) 0x60d02898 is located 0 bytes to the right of 136-byte region [0x60d02810,0x60d02898) allocated by thread T0 here: #0 0x7f0cad19f350 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9350) #1 0x563324cdccf3 in sqlite3MemMalloc /root/Documents/sqlite-autoconf-3270200/sqlite3.c:22837 SUMMARY: AddressSanitizer: heap-buffer-overflow (/lib/x86_64-linux-gnu/libasan.so.5+0xb86a2) Shadow bytes around the buggy address: 0x0c1a7fff84c0: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fd fd 0x0c1a7fff84d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c1a7fff84e0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x0c1a7fff84f0: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa 0x0c1a7fff8500: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c1a7fff8510: 00 00 00[fa]fa fa fa fa fa fa fa fa fd fd fd fd 0x0c1a7fff8520: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa 0x0c1a7fff8530: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00 0x0c1a7fff8540: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa 0x0c1a7fff8550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c1a7fff8560: 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user:f7 Container overflow: fc Array cookie:ac Intra object redzone:bb ASan internal: fe Left alloca redzone: ca Right alloca redzone:cb ==21007==ABORTING ``` View detail in gdb: ``` (gdb) r < 2-oob-read.sql Starting program: /root/Documents/sqlite-autoconf-3270200/sqlite3 < 2-oob-read.sql [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, 0x5564200f in fts5HashEntrySort (pHash=0x60402018,