Package: libsqlite3-0
Version: 3.7.13-1
Severity: normal
Tags: upstream patch

Dear Maintainer,

SQLite added a feature (in 3.7.11 I think) to ensure that journal/wal
files have the same permissions as the database file:

http://www.sqlite.org/src/info/84b324606a

The implementation sets umask to 0 for short periods of time and 
this is a problem when SQLite is used in a multi-threaded process
because the umask change affects all threads in the process.  Other
threads creating files while the umask is 0 will create files with
global write access rather than with permissions limited by umask.

The 3.7.16 release contains a fix to use fchmod instead of umask:

http://www.sqlite.org/src/info/6c4c2b7dba

The 3.7.13-1 version in testing is vulnerable.

Index: src/os_unix.c
==================================================================
--- src/os_unix.c
+++ src/os_unix.c
@@ -410,15 +410,11 @@
   { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
 #endif
 #define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
                     aSyscall[13].pCurrent)
 
-#if SQLITE_ENABLE_LOCKING_STYLE
   { "fchmod",       (sqlite3_syscall_ptr)fchmod,     0  },
-#else
-  { "fchmod",       (sqlite3_syscall_ptr)0,          0  },
-#endif
 #define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)
 
 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
   { "fallocate",    (sqlite3_syscall_ptr)posix_fallocate,  0 },
 #else
@@ -439,13 +435,10 @@
 #define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
 
   { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
 #define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
 
-  { "umask",        (sqlite3_syscall_ptr)umask,           0 },
-#define osUmask     ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
-
 }; /* End of the overrideable system calls */
 
 /*
 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
 ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
@@ -546,31 +539,29 @@
 ** process that is able to write to the database will also be able to
 ** recover the hot journals.
 */
 static int robust_open(const char *z, int f, mode_t m){
   int fd;
-  mode_t m2;
-  mode_t origM = 0;
-  if( m==0 ){
-    m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
-  }else{
-    m2 = m;
-    origM = osUmask(0);
-  }
+  mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
   do{
 #if defined(O_CLOEXEC)
     fd = osOpen(z,f|O_CLOEXEC,m2);
 #else
     fd = osOpen(z,f,m2);
 #endif
   }while( fd<0 && errno==EINTR );
-  if( m ){
-    osUmask(origM);
-  }
+  if( fd>=0 ){
+    if( m!=0 ){
+      struct stat statbuf;
+      if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
+        osFchmod(fd, m);
+      }
+    }
 #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
-  if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+    osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
 #endif
+  }
   return fd;
 }
 
 /*
 ** Helper functions to obtain and relinquish the global mutex. The
@@ -6992,11 +6983,11 @@
   };
   unsigned int i;          /* Loop counter */
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==22 );
+  assert( ArraySize(aSyscall)==21 );
 
   /* Register all VFSes defined in the aVfs[] array */
   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
     sqlite3_vfs_register(&aVfs[i], i==0);
   }

Index: test/pager1.test
==================================================================
--- test/pager1.test
+++ test/pager1.test
@@ -881,16 +881,24 @@
   COMMIT;
 } {delete}
 tv filter {}
 db close
 tv delete 
+catch {
+  test_syscall install fchmod
+  test_syscall fault 1 1
+}
 do_test pager1.4.7.2 {
   faultsim_restore_and_reopen
   catch {file attributes test.db-journal -permissions r--------}
   catch {file attributes test.db-journal -readonly 1}
   catchsql { SELECT * FROM t1 }
 } {1 {unable to open database file}}
+catch {
+  test_syscall reset
+  test_syscall fault 0 0
+}
 do_test pager1.4.7.3 {
   db close
   catch {file attributes test.db-journal -permissions rw-rw-rw-}
   catch {file attributes test.db-journal -readonly 0}
   delete_file test.db-journal

Index: test/tkt3457.test
==================================================================
--- test/tkt3457.test
+++ test/tkt3457.test
@@ -30,11 +30,11 @@
 #                the hot-journal file. Result: SQLITE_CANTOPEN.
 #                
 #   tkt3457-1.3: Application has write but not read permission on
 #                the hot-journal file. Result: SQLITE_CANTOPEN.
 #
-#   tkt3457-1.4: Application has read but not write permission on
+#   tkt3457-1.4: Application has read but not write permission ongrep
 #                the hot-journal file. Result: SQLITE_CANTOPEN.
 #
 #   tkt3457-1.5: Application has read/write permission on the hot-journal 
 #                file. Result: SQLITE_OK.
 # 
@@ -59,10 +59,18 @@
   puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"
   close $fd
 
   execsql COMMIT
 } {}
+
+# Disable fchmod to make sure SQLite itself does not try to change the
+# permission bits on us
+#
+catch {
+  test_syscall install fchmod
+  test_syscall fault 1 1
+}
 
 do_test tkt3457-1.2 {
   forcecopy bak.db-journal test.db-journal
   file attributes test.db-journal -permissions ---------
   catchsql { SELECT * FROM t1 }
@@ -81,7 +89,13 @@
 do_test tkt3457-1.5 {
   forcecopy bak.db-journal test.db-journal
   file attributes test.db-journal -permissions rw-rw-rw-
   catchsql { SELECT * FROM t1 }
 } {0 {1 2 3 4 5 6}}
+
+# Reenable fchmod
+catch {
+  test_syscall uninstall
+  test_syscall fault 0 0
+}
 
 finish_test

-- System Information:
Debian Release: 7.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libsqlite3-0 depends on:
ii  libc6              2.13-38
ii  multiarch-support  2.13-38

libsqlite3-0 recommends no packages.

libsqlite3-0 suggests no packages.

-- no debconf information


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to