/ Check-in [ed53b645]
Login

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

Overview
Comment:Only call fchown when running as root and supporting files mismatch the database owner & perms
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: ed53b645cc791e2c75885866ecb668fff14f8e7e
User & Date: adam 2012-05-31 00:21:28
Context
2012-06-08
01:13
Merge trunk changes into the apple-osx branch. check-in: 9d1b8515 user: drh tags: apple-osx
2012-05-31
00:21
Only call fchown when running as root and supporting files mismatch the database owner & perms check-in: ed53b645 user: adam tags: apple-osx
2012-05-22
13:11
Version 3.7.12.1 check-in: 972e75bb user: drh tags: apple-osx
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731


4732
4733
4734
4735
4736
4737
4738
....
5253
5254
5255
5256
5257
5258
5259

5260
5261
5262
5263
5264



5265

5266
5267
5268
5269
5270
5271
5272
....
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358

6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
      }
      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
      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) ){
          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
        }else{
          /* If running as root set the uid/gid of the shm file to match
          ** the database */
          uid_t euid = geteuid();
          if( euid==0 && (euid!=sStat.st_uid || getegid()!=sStat.st_gid) ){
            if( fchown(pShmNode->h, sStat.st_uid, sStat.st_gid) ){
              rc = SQLITE_IOERR_SHMOPEN;


            }
          }
        }
      }
      if( rc==SQLITE_OK ){
        rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
      }
................................................................................
      return rc;
    }
    rc = SQLITE_OK; /* Ignore the locking failure if force is true */
  }
  if( (bFlags&SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK)!=0 ){
    /* initialize a new database in TMPDIR and copy the contents over */
    const char *tDir = unixTempFileDir();

    int tLen = sizeof(char) * (strlen(tDir) + 11);
    char *tDbPath = (char *)malloc(tLen);
    int tFd = -1;
    
    strlcpy(tDbPath, tDir, tLen);



    strlcat(tDbPath, "tmpdbXXXXX", tLen);

    tFd = mkstemp(tDbPath);
    if( tFd==-1 ){
      storeLastErrno(pFile, errno);
      rc = SQLITE_IOERR;
      safeFailed = 1;
    }else{
      sqlite3 *tDb = NULL;
................................................................................
      goto open_finished;
    }
    /* if we're opening the wal or journal and running as root, set the
    ** journal uid/gid */
    if( !isReadonly && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL)) ){
      uid_t euid = geteuid();
      if( euid==0 && (euid!=uid || getegid()!=gid) ){
        if( fchown(fd, uid, gid) ){
          rc = SQLITE_CANTOPEN_BKPT;
          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;
  }

  if( p->pUnused ){







<
<
<
<
<
<
<
<
<
<
<











|
|

>
>







 







>
|




>
>
>
|
>







 







|



>


<
<
<
<
<
<
<
<
<
<
<







4700
4701
4702
4703
4704
4705
4706











4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
....
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
....
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357











6358
6359
6360
6361
6362
6363
6364
      }
      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
      if( pShmNode->h<0 ){
        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
        goto shm_open_err;
      }












      /* 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) ){
          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
        }else{
          /* If running as root set the uid/gid of the shm file to match
          ** the database */
          uid_t euid = geteuid();
          if( (!pShmNode->isReadonly) && euid==0 && (euid!=sStat.st_uid || getegid()!=sStat.st_gid) ){
            if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid) ){
              rc = SQLITE_IOERR_SHMOPEN;
            }else{
              pDbFd->ctrlFlags |= UNIXFILE_CHOWN;
            }
          }
        }
      }
      if( rc==SQLITE_OK ){
        rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
      }
................................................................................
      return rc;
    }
    rc = SQLITE_OK; /* Ignore the locking failure if force is true */
  }
  if( (bFlags&SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK)!=0 ){
    /* initialize a new database in TMPDIR and copy the contents over */
    const char *tDir = unixTempFileDir();
    int tDirLen = strlen(tDir);
    int tLen = sizeof(char) * (tDirLen + 12);
    char *tDbPath = (char *)malloc(tLen);
    int tFd = -1;
    
    strlcpy(tDbPath, tDir, tLen);
    if( tDbPath[(tDirLen-1)] != '/' ){
      strlcat(tDbPath, "/tmpdbXXXXX", tLen);
    } else {
      strlcat(tDbPath, "tmpdbXXXXX", tLen);
    }
    tFd = mkstemp(tDbPath);
    if( tFd==-1 ){
      storeLastErrno(pFile, errno);
      rc = SQLITE_IOERR;
      safeFailed = 1;
    }else{
      sqlite3 *tDb = NULL;
................................................................................
      goto open_finished;
    }
    /* if we're opening the wal or journal and running as root, set the
    ** journal uid/gid */
    if( !isReadonly && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL)) ){
      uid_t euid = geteuid();
      if( euid==0 && (euid!=uid || getegid()!=gid) ){
        if( osFchown(fd, uid, gid) ){
          rc = SQLITE_CANTOPEN_BKPT;
          goto open_finished;
        }
        p->ctrlFlags |= UNIXFILE_CHOWN;
      }
    }











  }
  assert( fd>=0 );
  if( pOutFlags ){
    *pOutFlags = flags;
  }

  if( p->pUnused ){