Our Android software uses a virtual file system (VFS) for SQLite, which has been working correctly. Once we began using it with Android 6 (Marshmallow) all sorts of weird errors started to occur with large negative offsets being passed to ftruncate(), stack overflows, data corruptions, etc. Using readelf
(among other tools), we eventually traced the problem to a change in the imports used by libsqlite.so
: Lollipop and earlier import ftruncate
and mmap
, the newest libraries import ftruncate64
and mmap64
. We "solved" the problem by changing which functions we use depending on the API version (Marshmallow is version 23):
/*
* Empirical testing of Tab S2 running Marshmallow revealed the SQLite
* unix_syscall table uses "ftruncate" and "mmap" as connection points,
* but the actual functions linked against are the *64 versions. This
* leads to stack corruption and all sorts of nasty errors as a result.
*/
if (getApiVersion() >= 23) // for Marshmallow
{ setUnixSystemCall(NULL, "ftruncate", our_ftruncate64);
setUnixSystemCall(NULL, "mmap", our_mmap64);
}
else // for Lollipop & older
{ setUnixSystemCall(NULL, "ftruncate", our_ftruncate);
setUnixSystemCall(NULL, "mmap", our_mmap);
}
Looking at the source code both from http://www.sqlite.org/2015/sqlite-amalgamation-3081002.zip and https://github.com/android/platform_external_sqlite/blob/master/dist/sqlite3.c all that the C
source calls is ftruncate
and mmap
which makes our methodology "questionable" at best.
How does libsqlite.so
import and use ftruncate64
and mmap64
where the source code only calls ftruncate
and mmap
? Are we not looking at the correct source code repository? Is there something going on at a link step? Did Marshmallow remove support for the non-64 bit versions of these functions?