/ Check-in [70c419a4]
Login

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

Overview
Comment:Avoid calling fchown() if the process is not running as root.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:70c419a434be77b042a23174483d6a411899eb5d
User & Date: drh 2012-05-31 13:10:49
Context
2012-06-05
13:56
Add sqlite3_quota_ferror() and sqlite3_quota_file_available() interfaces to test_quota.c. Change sqlite3_quota_fwrite() to use a const input buffer. check-in: 61669c95 user: drh tags: trunk
2012-06-02
14:32
The sqlite3_close() interface returns SQLITE_OK even if there are outstanding sqlite3_stmt and sqlite3_backup objects. The connection becomes a zombie. Resource deallocation is deferred until the last sqlite3_stmt or sqlite3_backup object closes. This is intended to help SQLite play nicer with garbage collectors. check-in: e276a02b user: drh tags: deferred-close
2012-05-31
13:10
Avoid calling fchown() if the process is not running as root. check-in: 70c419a4 user: drh tags: trunk
2012-05-29
19:25
Link the NDEBUG macro to SQLITE_DEBUG so that when SQLITE_DEBUG is defined, NDEBUG is automatically undefined an dwhen SQLITE_DEBUG is undefined NDEBUG is automatically defined. check-in: 07935d10 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
303
304
305
306
307
308
309









310
311
312
313
314
315
316
...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
....
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
....
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
#else
# define UNIXFILE_DIRSYNC    0x00
#endif
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
#define UNIXFILE_DELETE      0x20     /* Delete on close */
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
#define UNIXFILE_CHOWN      0x100     /* File ownership was changed */

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
................................................................................
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
  return open(zFile, flags, mode);
}










/* Forward reference */
static int openDirectory(const char*, int*);

/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
................................................................................

  { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
#define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)

  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)

  { "fchown",       (sqlite3_syscall_ptr)fchown,          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 */

................................................................................
      if( pShmNode->h<0 ){
        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
        goto shm_open_err;
      }

      /* If this process is running as root, make sure that the SHM file
      ** is owned by the same user that owns the original database.  Otherwise,
      ** the original owner will not be able to connect. If this process is
      ** not root, the following fchown() will fail, but we don't care.  The
      ** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler
      ** warnings.
      */
      if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){
        pDbFd->ctrlFlags |= UNIXFILE_CHOWN;
      }
  
      /* Check to see if another process is holding the dead-man switch.
      ** If not, truncate the file to zero length. 
      */
      rc = SQLITE_OK;
      if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
        if( robust_ftruncate(pShmNode->h, 0) ){
................................................................................
    if( fd<0 ){
      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
      goto open_finished;
    }

    /* If this process is running as root and if creating a new rollback
    ** journal or WAL file, set the ownership of the journal or WAL to be
    ** the same as the original database.  If we are not running as root,
    ** then the fchown() call will fail, but that's ok.  The "if(){}" and
    ** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler
    ** warnings from gcc.
    */
    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
      if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; }
    }
  }
  assert( fd>=0 );
  if( pOutFlags ){
    *pOutFlags = flags;
  }








<







 







>
>
>
>
>
>
>
>
>







 







|







 







|
<
<
<

|
<
<







 







|
<
<
<


|







258
259
260
261
262
263
264

265
266
267
268
269
270
271
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
....
3948
3949
3950
3951
3952
3953
3954
3955



3956
3957


3958
3959
3960
3961
3962
3963
3964
....
5156
5157
5158
5159
5160
5161
5162
5163



5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
#else
# define UNIXFILE_DIRSYNC    0x00
#endif
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
#define UNIXFILE_DELETE      0x20     /* Delete on close */
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */


/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
................................................................................
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
  return open(zFile, flags, mode);
}

/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes.  So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
  return geteuid() ? 0 : fchown(fd,uid,gid);
}

/* Forward reference */
static int openDirectory(const char*, int*);

/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
................................................................................

  { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
#define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)

  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
#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 */

................................................................................
      if( pShmNode->h<0 ){
        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
        goto shm_open_err;
      }

      /* If this process is running as root, make sure that the SHM file
      ** is owned by the same user that owns the original database.  Otherwise,
      ** the original owner will not be able to connect.



      */
      osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);


  
      /* Check to see if another process is holding the dead-man switch.
      ** If not, truncate the file to zero length. 
      */
      rc = SQLITE_OK;
      if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
        if( robust_ftruncate(pShmNode->h, 0) ){
................................................................................
    if( fd<0 ){
      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
      goto open_finished;
    }

    /* If this process is running as root and if creating a new rollback
    ** journal or WAL file, set the ownership of the journal or WAL to be
    ** the same as the original database.



    */
    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
      osFchown(fd, uid, gid);
    }
  }
  assert( fd>=0 );
  if( pOutFlags ){
    *pOutFlags = flags;
  }