/ Check-in [6b236069]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Make the openDirectory routine in os_unix.c overrideable so that it can be turned into a harmless no-op for the chromium sandbox.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6b236069e1ea3c99ff0a007a790d4baebda70b13
User & Date: drh 2011-08-10 01:52:12
Context
2011-08-12
16:47
Merge the experimental changes to use a merge-sort when creating an index into the trunk. check-in: 346a453d user: dan tags: trunk
16:30
Merge latest trunk changes into experimental branch. check-in: 7e515055 user: dan tags: experimental
01:51
Begin a branch that experimentally replaces sqlite_stat2 with a new table called sqlite_stat3 that will hopefully facilitate better query planning decisions. check-in: 52e1d7e8 user: drh tags: stat3-enhancement
2011-08-10
01:52
Make the openDirectory routine in os_unix.c overrideable so that it can be turned into a harmless no-op for the chromium sandbox. check-in: 6b236069 user: drh tags: trunk
2011-08-09
18:14
Add command-line utilities "offsets.c" and "extract.c" for use in low-level analyzsis of database files. check-in: dfa22ed4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

   294    294   ** The safest way to deal with the problem is to always use this wrapper
   295    295   ** which always has the same well-defined interface.
   296    296   */
   297    297   static int posixOpen(const char *zFile, int flags, int mode){
   298    298     return open(zFile, flags, mode);
   299    299   }
   300    300   
          301  +/* Forward reference */
          302  +static int openDirectory(const char*, int*);
          303  +
   301    304   /*
   302    305   ** Many system calls are accessed through pointer-to-functions so that
   303    306   ** they may be overridden at runtime to facilitate fault injection during
   304    307   ** testing and sandboxing.  The following array holds the names and pointers
   305    308   ** to all overrideable system calls.
   306    309   */
   307    310   static struct unix_syscall {
................................................................................
   393    396     { "fallocate",    (sqlite3_syscall_ptr)0,                0 },
   394    397   #endif
   395    398   #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
   396    399   
   397    400     { "unlink",       (sqlite3_syscall_ptr)unlink,           0 },
   398    401   #define osUnlink    ((int(*)(const char*))aSyscall[16].pCurrent)
   399    402   
          403  +  { "openDirectory",    (sqlite3_syscall_ptr)openDirectory,      0 },
          404  +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
          405  +
   400    406   }; /* End of the overrideable system calls */
   401    407   
   402    408   /*
   403    409   ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
   404    410   ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
   405    411   ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
   406    412   ** system call named zName.
................................................................................
  3247   3253   
  3248   3254   /*
  3249   3255   ** Open a file descriptor to the directory containing file zFilename.
  3250   3256   ** If successful, *pFd is set to the opened file descriptor and
  3251   3257   ** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
  3252   3258   ** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
  3253   3259   ** value.
         3260  +**
         3261  +** The directory file descriptor is used for only one thing - to
         3262  +** fsync() a directory to make sure file creation and deletion events
         3263  +** are flushed to disk.  Such fsyncs are not needed on newer
         3264  +** journaling filesystems, but are required on older filesystems.
         3265  +**
         3266  +** This routine can be overridden using the xSetSysCall interface.
         3267  +** The ability to override this routine was added in support of the
         3268  +** chromium sandbox.  Opening a directory is a security risk (we are
         3269  +** told) so making it overrideable allows the chromium sandbox to
         3270  +** replace this routine with a harmless no-op.  To make this routine
         3271  +** a no-op, replace it with a stub that returns SQLITE_OK but leaves
         3272  +** *pFd set to a negative number.
  3254   3273   **
  3255   3274   ** If SQLITE_OK is returned, the caller is responsible for closing
  3256   3275   ** the file descriptor *pFd using close().
  3257   3276   */
  3258   3277   static int openDirectory(const char *zFilename, int *pFd){
  3259   3278     int ii;
  3260   3279     int fd = -1;
................................................................................
  3314   3333     SimulateIOError( rc=1 );
  3315   3334     if( rc ){
  3316   3335       pFile->lastErrno = errno;
  3317   3336       return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
  3318   3337     }
  3319   3338   
  3320   3339     /* Also fsync the directory containing the file if the DIRSYNC flag
  3321         -  ** is set.  This is a one-time occurrance.  Many systems (examples: AIX
  3322         -  ** or any process running inside a chromium sandbox) are unable to fsync a
  3323         -  ** directory, so ignore errors.
         3340  +  ** is set.  This is a one-time occurrance.  Many systems (examples: AIX)
         3341  +  ** are unable to fsync a directory, so ignore errors on the fsync.
  3324   3342     */
  3325   3343     if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
  3326   3344       int dirfd;
  3327   3345       OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
  3328   3346               HAVE_FULLFSYNC, isFullsync));
  3329         -    openDirectory(pFile->zPath, &dirfd);
  3330         -    if( dirfd>=0 ){
         3347  +    rc = osOpenDirectory(pFile->zPath, &dirfd);
         3348  +    if( rc==SQLITE_OK && dirfd>=0 ){
  3331   3349         full_fsync(dirfd, 0, 0);
  3332   3350         robust_close(pFile, dirfd, __LINE__);
  3333   3351       }
  3334   3352       pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
  3335   3353     }
  3336   3354     return rc;
  3337   3355   }
................................................................................
  5142   5160     SimulateIOError(return SQLITE_IOERR_DELETE);
  5143   5161     if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
  5144   5162       return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
  5145   5163     }
  5146   5164   #ifndef SQLITE_DISABLE_DIRSYNC
  5147   5165     if( dirSync ){
  5148   5166       int fd;
  5149         -    rc = openDirectory(zPath, &fd);
         5167  +    rc = osOpenDirectory(zPath, &fd);
  5150   5168       if( rc==SQLITE_OK ){
  5151   5169   #if OS_VXWORKS
  5152   5170         if( fsync(fd)==-1 )
  5153   5171   #else
  5154   5172         if( fsync(fd) )
  5155   5173   #endif
  5156   5174         {
................................................................................
  6715   6733       UNIXVFS("unix-proxy",    proxyIoFinder ),
  6716   6734   #endif
  6717   6735     };
  6718   6736     unsigned int i;          /* Loop counter */
  6719   6737   
  6720   6738     /* Double-check that the aSyscall[] array has been constructed
  6721   6739     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  6722         -  assert( ArraySize(aSyscall)==17 );
         6740  +  assert( ArraySize(aSyscall)==18 );
  6723   6741   
  6724   6742     /* Register all VFSes defined in the aVfs[] array */
  6725   6743     for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
  6726   6744       sqlite3_vfs_register(&aVfs[i], i==0);
  6727   6745     }
  6728   6746     return SQLITE_OK; 
  6729   6747   }

Changes to test/syscall.test.

    55     55   
    56     56   #-------------------------------------------------------------------------
    57     57   # Tests for the xNextSystemCall method.
    58     58   #
    59     59   foreach s {
    60     60       open close access getcwd stat fstat ftruncate
    61     61       fcntl read pread write pwrite fchmod fallocate
    62         -    pread64 pwrite64 unlink
           62  +    pread64 pwrite64 unlink openDirectory
    63     63   } {
    64     64     if {[test_syscall exists $s]} {lappend syscall_list $s}
    65     65   }
    66     66   do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list]
    67     67   
    68     68   #-------------------------------------------------------------------------
    69     69   # This test verifies that if a call to open() fails and errno is set to