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

Reply via email to