On 7/15/15, T?r?k Edwin <edwin+sqlite3 at etorok.net> wrote: >> >> 1) unknown-crash (might be due to some alignment requirements in asan): > > Build with clang 3.4 shows a heap-use-after-free instead of unknown-crash, > and building a normal (just ./configure) executable with GCC and running > under valgrind shows an invalid read too, so this > does seem to be a real bug after all:
This is not a heap-use-after-free. This is a read-past-end-of-buffer. (Probably clang is confused because the buffer we are reading off the end of is immediately followed by another allocation that was previously freed.) The is a *read* off the end of a buffer only - not a write. And it only comes up on certain types of very obscure database file corruption. Basically, you have to engineer the database corruption to make this happen - it will never occur by accident. SQLite can be made to detect the database corruption prior to the buffer over-read by setting: PRAGMA cell_size_check=ON; See https://www.sqlite.org/draft/pragma.html#pragma_cell_size_check for additional information on the cell_size_check pragma. Turning cell_size_check on will always prevent the buffer overread, but it also involves a noticeable performance hit. So it is off by default, since the vast majority of the billions of SQLite instances out there will never encounter a maliciously corrupted database file, and even if they do the worst that can happen is a buffer over-*read* not an over-write, and hence is not a security concern. That said, applications that open and read SQLite database files received from untrusted sources, might want to set cell_size_check=ON out of an abundance of caution. Give fuzzcheck the --cell-size-check command-line option to engage the cell_size_check pragma, in order to prevent problems being reported by -fsanitize or by valgrind. You will notice that we already do the same in the "valgrindfuzz" target of the makefile: https://www.sqlite.org/src/artifact/6e8af213?ln=1050 > > ==14598== Invalid read of size 1 > ==14598== at 0x4A0C9CE: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:915) > ==14598== by 0x426804: rebuildPage (sqlite3.c:60141) > ==14598== by 0x4421BA: editPage (sqlite3.c:60370) > ==14598== by 0x4421BA: balance_nonroot (sqlite3.c:61299) > ==14598== by 0x442888: balance (sqlite3.c:61547) > ==14598== by 0x445051: sqlite3BtreeInsert (sqlite3.c:61737) > ==14598== by 0x45A57D: sqlite3VdbeExec (sqlite3.c:76236) > ==14598== by 0x461986: sqlite3Step (sqlite3.c:70639) > ==14598== by 0x461986: sqlite3_step (sqlite3.c:70700) > ==14598== by 0x407A51: runSql (fuzzcheck.c:617) > ==14598== by 0x406C92: main (fuzzcheck.c:975) > ==14598== Address 0x4ca3a10 is 0 bytes after a block of size 512 alloc'd > ==14598== at 0x4A07C20: malloc (vg_replace_malloc.c:296) > ==14598== by 0x426B70: sqlite3MemMalloc (sqlite3.c:17235) > ==14598== by 0x40EDAC: mallocWithAlarm (sqlite3.c:20909) > ==14598== by 0x40EDAC: sqlite3Malloc (sqlite3.c:20940) > ==14598== by 0x40FA0A: pcache1Alloc (sqlite3.c:40705) > ==14598== by 0x412507: sqlite3PageMalloc (sqlite3.c:40843) > ==14598== by 0x412507: sqlite3PagerSetPagesize (sqlite3.c:45907) > ==14598== by 0x44796B: sqlite3BtreeOpen (sqlite3.c:56012) > ==14598== by 0x4792A6: openDatabase (sqlite3.c:132083) > ==14598== by 0x406C4B: main (fuzzcheck.c:965) > ==14598== > ==14598== Invalid read of size 1 > ==14598== at 0x4A0C9C0: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:915) > ==14598== by 0x426804: rebuildPage (sqlite3.c:60141) > ==14598== by 0x4421BA: editPage (sqlite3.c:60370) > ==14598== by 0x4421BA: balance_nonroot (sqlite3.c:61299) > ==14598== by 0x442888: balance (sqlite3.c:61547) > ==14598== by 0x445051: sqlite3BtreeInsert (sqlite3.c:61737) > ==14598== by 0x45A57D: sqlite3VdbeExec (sqlite3.c:76236) > ==14598== by 0x461986: sqlite3Step (sqlite3.c:70639) > ==14598== by 0x461986: sqlite3_step (sqlite3.c:70700) > ==14598== by 0x407A51: runSql (fuzzcheck.c:617) > ==14598== by 0x406C92: main (fuzzcheck.c:975) > ==14598== Address 0x4ca3a12 is 2 bytes after a block of size 512 alloc'd > ==14598== at 0x4A07C20: malloc (vg_replace_malloc.c:296) > ==14598== by 0x426B70: sqlite3MemMalloc (sqlite3.c:17235) > ==14598== by 0x40EDAC: mallocWithAlarm (sqlite3.c:20909) > ==14598== by 0x40EDAC: sqlite3Malloc (sqlite3.c:20940) > ==14598== by 0x40FA0A: pcache1Alloc (sqlite3.c:40705) > ==14598== by 0x412507: sqlite3PageMalloc (sqlite3.c:40843) > ==14598== by 0x412507: sqlite3PagerSetPagesize (sqlite3.c:45907) > ==14598== by 0x44796B: sqlite3BtreeOpen (sqlite3.c:56012) > ==14598== by 0x4792A6: openDatabase (sqlite3.c:132083) > ==14598== by 0x406C4B: main (fuzzcheck.c:965) > > > ./fuzzcheck /home/edwin/skylable/sqlite/test/fuzzdata3.db > fuzzdata3.db: Database fuzz as of 2015-06-24 > fuzzdata3.db: 0% 10%/home/edwin/skylable/sqlite/sqlite3.c:24327: runtime > error: value 9e+323 is outside the range of representable values of type > 'double' > /home/edwin/skylable/sqlite/sqlite3.c:24327: runtime error: value 9e+323 is > outside the range of representable values of type 'double' > ================================================================= > ==10788==ERROR: AddressSanitizer: heap-use-after-free on address > 0x6150002abac1 at pc 0x840bac bp 0x7ffdfa9ec640 sp 0x7ffdfa9ec638 > READ of size 385 at 0x6150002abac1 thread T0 > #0 0x840bab in rebuildPage /home/edwin/skylable/sqlite/sqlite3.c:60141 > #1 0x83ad8e in editPage /home/edwin/skylable/sqlite/sqlite3.c:60370 > #2 0x83ad8e in balance_nonroot > /home/edwin/skylable/sqlite/sqlite3.c:61299 > #3 0x828d2f in balance /home/edwin/skylable/sqlite/sqlite3.c:61547 > #4 0x7e278e in sqlite3BtreeInsert > /home/edwin/skylable/sqlite/sqlite3.c:61737 > #5 0x7b16a8 in sqlite3VdbeExec > /home/edwin/skylable/sqlite/sqlite3.c:76236 > #6 0x4c75f9 in sqlite3Step /home/edwin/skylable/sqlite/sqlite3.c:70639 > #7 0x4c62b7 in sqlite3_step /home/edwin/skylable/sqlite/sqlite3.c:70700 > #8 0x488bc8 in runSql /home/edwin/skylable/sqlite/test/fuzzcheck.c:617 > #9 0x486338 in main /home/edwin/skylable/sqlite/test/fuzzcheck.c:975 > #10 0x3452621b44 (/lib/x86_64-linux-gnu/libc.so.6+0x3452621b44) > #11 0x48442c in _start (/home/edwin/skylable/sqlite/fuzzcheck+0x48442c) > > 0x6150002abc00 is located 0 bytes to the right of 512-byte region > [0x6150002aba00,0x6150002abc00) > freed by thread T0 here: > #0 0x46e1c9 in free > /home/edwin/tools/stack/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64 > #1 0x507811 in sqlite3_free /home/edwin/skylable/sqlite/sqlite3.c:21118 > #2 0x507811 in pcache1Free /home/edwin/skylable/sqlite/sqlite3.c:40746 > #3 0x7b3b51 in sqlite3PageFree > /home/edwin/skylable/sqlite/sqlite3.c:40850 > #4 0x7b3b51 in sqlite3BtreeIntegrityCheck > /home/edwin/skylable/sqlite/sqlite3.c:63015 > #5 0x7b3b51 in sqlite3VdbeExec > /home/edwin/skylable/sqlite/sqlite3.c:77288 > #6 0x4c75f9 in sqlite3Step /home/edwin/skylable/sqlite/sqlite3.c:70639 > #7 0x4c62b7 in sqlite3_step /home/edwin/skylable/sqlite/sqlite3.c:70700 > #8 0x488bc8 in runSql /home/edwin/skylable/sqlite/test/fuzzcheck.c:617 > #9 0x486338 in main /home/edwin/skylable/sqlite/test/fuzzcheck.c:975 > #10 0x3452621b44 (/lib/x86_64-linux-gnu/libc.so.6+0x3452621b44) > > previously allocated by thread T0 here: > #0 0x46e349 in __interceptor_malloc > /home/edwin/tools/stack/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 > #1 0x575831 in sqlite3MemMalloc > /home/edwin/skylable/sqlite/sqlite3.c:17235 > #2 0x492fe9 in mallocWithAlarm > /home/edwin/skylable/sqlite/sqlite3.c:20909 > #3 0x492fe9 in sqlite3Malloc > /home/edwin/skylable/sqlite/sqlite3.c:20940 > #4 0x50afd7 in pcache1Alloc /home/edwin/skylable/sqlite/sqlite3.c:40705 > #5 0x7a9f2c in sqlite3PageMalloc > /home/edwin/skylable/sqlite/sqlite3.c:40843 > #6 0x7a9f2c in sqlite3BtreeIntegrityCheck > /home/edwin/skylable/sqlite/sqlite3.c:62958 > #7 0x7a9f2c in sqlite3VdbeExec > /home/edwin/skylable/sqlite/sqlite3.c:77288 > #8 0x4c75f9 in sqlite3Step /home/edwin/skylable/sqlite/sqlite3.c:70639 > #9 0x4c62b7 in sqlite3_step /home/edwin/skylable/sqlite/sqlite3.c:70700 > #10 0x488bc8 in runSql /home/edwin/skylable/sqlite/test/fuzzcheck.c:617 > #11 0x486338 in main /home/edwin/skylable/sqlite/test/fuzzcheck.c:975 > #12 0x3452621b44 (/lib/x86_64-linux-gnu/libc.so.6+0x3452621b44) > > SUMMARY: AddressSanitizer: heap-use-after-free > /home/edwin/skylable/sqlite/sqlite3.c:60141 rebuildPage > Shadow bytes around the buggy address: > 0x0c2a8004d700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c2a8004d710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c2a8004d720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x0c2a8004d730: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c2a8004d740: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > =>0x0c2a8004d750: fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd > 0x0c2a8004d760: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > 0x0c2a8004d770: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > 0x0c2a8004d780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0c2a8004d790: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > 0x0c2a8004d7a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > 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 > Heap right redzone: fb > Freed heap region: fd > Stack left redzone: f1 > Stack mid redzone: f2 > Stack right redzone: f3 > Stack partial redzone: f4 > Stack after return: f5 > Stack use after scope: f8 > Global redzone: f9 > Global init order: f6 > Poisoned by user: f7 > ASan internal: fe > ==10788==ABORTING > > > _______________________________________________ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > -- D. Richard Hipp drh at sqlite.org