SQLite

Check-in [ed53b645cc]
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
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: ed53b645cc791e2c75885866ecb668fff14f8e7e
User & Date: adam 2012-05-31 00:21:28.876
Context
2012-06-08
01:13
Merge trunk changes into the apple-osx branch. (check-in: 9d1b851562 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: ed53b645cc user: adam tags: apple-osx)
2012-05-22
13:11
Version 3.7.12.1 (check-in: 972e75bb5d user: drh tags: apple-osx)
Changes
Unified Diff 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
      }
      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);
      }







<
<
<
<
<
<
<
<
<
<
<











|
|

>
>







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
      }
      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);
      }
5253
5254
5255
5256
5257
5258
5259

5260
5261
5262
5263
5264



5265

5266
5267
5268
5269
5270
5271
5272
      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;







>
|




>
>
>
|
>







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
      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;
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
      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;
  }








|



>

<
<
<
<
<
<
<
<
<
<
<







6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356











6357
6358
6359
6360
6361
6362
6363
      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;
  }