summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Storsjo2014-11-19 11:10:48 +0200
committerNarayan Kamath2014-11-19 14:25:01 +0000
commit006c79750f8494ea445316f608905216693c6814 (patch)
treefcf6dcd841adc8342c418675cd2307b5acb1b902
parenteb7bb20892840c34e4eba63d732d5b8087d04a73 (diff)
Store inodes in unsigned long long
In 32 bit ABIs, ino_t is a 32 bit type, while the st_ino field in struct stat is 64 bits wide in both 32 and 64 bit processes. This means that struct stat can expose inode numbers that are truncated when stored in an ino_t. The SDCard fuse daemon (/system/bin/sdcard) uses raw pointer values as inode numbers, so on 64 bit devices, we're very likely to observe inodes that need > 32 bits to represent. The fileHasMoved function in sqlite compares the stored inode value with a new one from stat, and when the stored value is truncated, this check will falsely indicate that the file has been moved. When the fileHasMoved function triggers, other functions start returning errors indicating that the database is in read-only mode. NOTE: Bionic differs from glibc in that struct stat's st_ino is *always* 64 bits wide, and not the same width as ino_t. bug: https://code.google.com/p/android/issues/detail?id=79994 bug: 18434265 (cherry picked from commit eef2c43133524ac629db4b083681c2bcc7542122) Change-Id: I832e0084e86c9a31519764d87df499ece05b488d
-rw-r--r--dist/Android.patch38
-rw-r--r--dist/sqlite3.c9
2 files changed, 35 insertions, 12 deletions
diff --git a/dist/Android.patch b/dist/Android.patch
index 4b8ef9d..f60126e 100644
--- a/dist/Android.patch
+++ b/dist/Android.patch
@@ -1,6 +1,6 @@
diff -r -u -d orig/shell.c ./shell.c
---- orig/shell.c 2014-08-20 16:26:07.117256041 -0700
-+++ ./shell.c 2014-08-20 16:45:00.468546769 -0700
+--- orig/shell.c 2014-10-03 12:18:31.191186450 +0100
++++ ./shell.c 2014-10-03 12:18:31.227186226 +0100
@@ -35,6 +35,11 @@
#include "sqlite3.h"
#include <ctype.h>
@@ -36,8 +36,8 @@ diff -r -u -d orig/shell.c ./shell.c
}
diff -r -u -d orig/sqlite3.c ./sqlite3.c
---- orig/sqlite3.c 2014-08-20 16:26:07.145255923 -0700
-+++ ./sqlite3.c 2014-08-20 16:26:36.205134826 -0700
+--- orig/sqlite3.c 2014-10-03 12:18:31.223186251 +0100
++++ ./sqlite3.c 2014-11-19 14:12:49.785181208 +0000
@@ -24109,6 +24109,13 @@
*/
#if SQLITE_OS_UNIX /* This file is used on unix only */
@@ -80,7 +80,23 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
-@@ -27909,7 +27927,7 @@
+@@ -25301,7 +25319,14 @@
+ #if OS_VXWORKS
+ struct vxworksFileId *pId; /* Unique file ID for vxworks. */
+ #else
+- ino_t ino; /* Inode number */
++#ifdef ANDROID
++ // Bionic's struct stat has a 64 bit st_ino on both 32 and
++ // 64 bit architectures. ino_t remains 32 bits wide on 32 bit
++ // architectures and can lead to inode truncation.
++ unsigned long long ino; /* Inode number */
++#else
++ ino_t ino; /* Inode number */
++#endif
+ #endif
+ };
+
+@@ -27909,7 +27934,7 @@
SimulateIOError( rc=1 );
if( rc!=0 ){
((unixFile*)id)->lastErrno = errno;
@@ -89,7 +105,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
}
*pSize = buf.st_size;
-@@ -27944,7 +27962,9 @@
+@@ -27944,7 +27969,9 @@
i64 nSize; /* Required file size */
struct stat buf; /* Used to hold return values of fstat() */
@@ -100,7 +116,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
if( nSize>(i64)buf.st_size ){
-@@ -28510,7 +28530,7 @@
+@@ -28510,7 +28537,7 @@
** with the same permissions.
*/
if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
@@ -109,7 +125,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
goto shm_open_err;
}
-@@ -29848,7 +29868,7 @@
+@@ -29848,7 +29875,7 @@
*pUid = sStat.st_uid;
*pGid = sStat.st_gid;
}else{
@@ -118,7 +134,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
}
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
-@@ -100867,7 +100887,7 @@
+@@ -100867,7 +100894,7 @@
}
if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
sqlite3SetString(pzErrMsg, db, "unsupported file format");
@@ -127,7 +143,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
goto initone_error_out;
}
-@@ -124770,9 +124790,9 @@
+@@ -124770,9 +124797,9 @@
#endif
#ifdef SQLITE_ENABLE_FTS3
@@ -140,7 +156,7 @@ diff -r -u -d orig/sqlite3.c ./sqlite3.c
#endif
#ifdef SQLITE_ENABLE_ICU
-@@ -130660,16 +130680,28 @@
+@@ -130660,16 +130687,28 @@
** module with sqlite.
*/
if( SQLITE_OK==rc
diff --git a/dist/sqlite3.c b/dist/sqlite3.c
index edd2045..e1aa127 100644
--- a/dist/sqlite3.c
+++ b/dist/sqlite3.c
@@ -25319,7 +25319,14 @@ struct unixFileId {
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID for vxworks. */
#else
- ino_t ino; /* Inode number */
+#ifdef ANDROID
+ // Bionic's struct stat has a 64 bit st_ino on both 32 and
+ // 64 bit architectures. ino_t remains 32 bits wide on 32 bit
+ // architectures and can lead to inode truncation.
+ unsigned long long ino; /* Inode number */
+#else
+ ino_t ino; /* Inode number */
+#endif
#endif
};