From: drh Date: Mon, 13 Feb 2012 20:16:37 +0000 (+0000) Subject: On unix, ignore the umask when creating journal files. That way, journal files X-Git-Tag: version-3.7.11~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8c815d14f88c68285508fbc4001a4cd1a0dd783b;p=thirdparty%2Fsqlite.git On unix, ignore the umask when creating journal files. That way, journal files will have exactly the same permissions as the original database and any process that has permission to write to the database can also recover hot journals. FossilOrigin-Name: 84b324606adc8437338c086404eb157f30f04130 --- diff --git a/manifest b/manifest index bdb31adf3a..014ff3285d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\svarious\stest\sscripts\sso\sthat\sveryquick.test\sruns\swith\sOMIT_COMPOUND_SELECT\sdefined. -D 2012-02-13T10:00:35.138 +C On\sunix,\signore\sthe\sumask\swhen\screating\sjournal\sfiles.\s\sThat\sway,\sjournal\sfiles\nwill\shave\sexactly\sthe\ssame\spermissions\sas\sthe\soriginal\sdatabase\sand\sany\nprocess\sthat\shas\spermission\sto\swrite\sto\sthe\sdatabase\scan\salso\srecover\nhot\sjournals. +D 2012-02-13T20:16:37.535 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 59beba555b65a450bd1d804220532971d4299f60 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c fd5875e602286c8ecd96a0049bd7869c30721df0 +F src/os_unix.c 8035d8af66d205b6bfd249c1ed0eb708c8411a3c F src/os_win.c 5ac061ae1326a71500cee578ed0fd9113b4f6a37 F src/pager.c 2d892f7b901a8867a33bc21742086165a3a99af8 F src/pager.h a435da8421dc7844b7f9c7f37b636c160c50208a @@ -548,7 +548,7 @@ F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1 -F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 +F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa @@ -709,7 +709,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 8a1bd9575ea1e8bdc0513fc5be7753fa4c3c04fb +F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 @@ -906,7 +906,7 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839 F test/wal.test edefe316b4125d7f68004ea53c5e73c398d436cc -F test/wal2.test f11883dd3cb7f647c5d2acfd7b5c6d4ba5770cc9 +F test/wal2.test 8871e7fd2c86711ff415a5817d68ea3101a15312 F test/wal3.test 6504bbf348b2d6dfade64a064f1050fd617e8706 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 @@ -989,7 +989,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bfbfe05b81919ecc3d6e7be4c24994f795f16582 -R 6250e4472fb78736176921352e48e2f9 -U dan -Z f0319cf74449ae83da7435ab8330767c +P 76bb649ee2633226324130f5898622c348f93769 +R b5d60671b244f9108cc239280d062aa2 +U drh +Z 7eb3e8117d2ffa2020d44f7552f02a09 diff --git a/manifest.uuid b/manifest.uuid index 896ec58a38..b443c6e1a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76bb649ee2633226324130f5898622c348f93769 \ No newline at end of file +84b324606adc8437338c086404eb157f30f04130 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 31fb1b40d9..ef6cba910a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -422,6 +422,9 @@ static struct unix_syscall { { "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 */ /* @@ -508,11 +511,36 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){ } /* -** Retry open() calls that fail due to EINTR +** Invoke open(). Do so multiple times, until it either succeeds or +** files for some reason other than EINTR. +** +** If the file creation mode "m" is 0 then set it to the default for +** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally +** 0644) as modified by the system umask. If m is not 0, then +** make the file creation mode be exactly m ignoring the umask. +** +** The m parameter will be non-zero only when creating -wal, -journal, +** and -shm files. We want those files to have *exactly* the same +** permissions as their original database, unadulterated by the umask. +** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a +** transaction crashes and leaves behind hot journals, then any +** 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, int m){ +static int robust_open(const char *z, int f, mode_t m){ int rc; - do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR ); + mode_t m2; + mode_t origM; + if( m==0 ){ + m2 = SQLITE_DEFAULT_FILE_PERMISSIONS; + }else{ + m2 = m; + origM = osUmask(0); + } + do{ rc = osOpen(z,f,m2); }while( rc<0 && errno==EINTR ); + if( m ){ + osUmask(origM); + } return rc; } @@ -3860,8 +3888,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ /* Call fstat() to figure out the permissions on the database file. If ** a new *-shm file is created, an attempt will be made to create it - ** with the same permissions. The actual permissions the file is created - ** with are subject to the current umask setting. + ** with the same permissions. */ if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ rc = SQLITE_IOERR_FSTAT; @@ -4892,12 +4919,10 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** written to *pMode. If an IO error occurs, an SQLite error code is ** returned and the value of *pMode is not modified. ** -** If the file being opened is a temporary file, it is always created with -** the octal permissions 0600 (read/writable by owner only). If the file -** is a database or master journal file, it is created with the permissions -** mask SQLITE_DEFAULT_FILE_PERMISSIONS. -** -** Finally, if the file being opened is a WAL or regular journal file, then +** In most cases cases, this routine sets *pMode to 0, which will become +** an indication to robust_open() to create the file using +** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. +** But if the file being opened is a WAL or regular journal file, then ** this function queries the file-system for the permissions on the ** corresponding database file and sets *pMode to this value. Whenever ** possible, WAL and journal files are created using the same permissions @@ -4916,7 +4941,7 @@ static int findCreateFileMode( gid_t *pGid /* OUT: gid to set on the file */ ){ int rc = SQLITE_OK; /* Return Code */ - *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS; + *pMode = 0; *pUid = 0; *pGid = 0; if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ @@ -5860,17 +5885,17 @@ static int proxyCreateUnixFile( } } if( fd<0 ){ - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); terrno = errno; if( fd<0 && errno==ENOENT && islockfile ){ if( proxyCreateLockPath(path) == SQLITE_OK ){ - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); } } } if( fd<0 ){ openFlags = O_RDONLY; - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); terrno = errno; } if( fd<0 ){ @@ -5994,8 +6019,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ goto end_breaklock; } /* write it out to the temporary break file */ - fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), - SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0); if( fd<0 ){ sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno); goto end_breaklock; @@ -6272,8 +6296,7 @@ static int proxyTakeConch(unixFile *pFile){ robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; - fd = robust_open(pCtx->dbPath, pFile->openFlags, - SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ pFile->h = fd; @@ -6842,7 +6865,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==21 ); + assert( ArraySize(aSyscall)==22 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ diff --git a/test/journal3.test b/test/journal3.test index f1bf89f8c7..939cc27c70 100644 --- a/test/journal3.test +++ b/test/journal3.test @@ -22,7 +22,9 @@ source $testdir/malloc_common.tcl # if {$::tcl_platform(platform) == "unix"} { - set umask [exec /bin/sh -c umask] + # Changed on 2012-02-13: umask is deliberately ignored for -wal, -journal, + # and -shm files. + #set umask [exec /bin/sh -c umask] faultsim_delete_and_reopen do_test journal3-1.1 { execsql { CREATE TABLE tx(y, z) } } {} @@ -33,7 +35,8 @@ if {$::tcl_platform(platform) == "unix"} { 4 00755 } { db close - set effective [format %.5o [expr $permissions & ~$umask]] + #set effective [format %.5o [expr $permissions & ~$umask]] + set effective $permissions do_test journal3-1.2.$tn.1 { catch { forcedelete test.db-journal } file attributes test.db -permissions $permissions diff --git a/test/syscall.test b/test/syscall.test index da7ecd53ba..d841a9a0b2 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -60,7 +60,7 @@ foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate pread64 pwrite64 unlink openDirectory mkdir rmdir - statvfs fchown + statvfs fchown umask } { if {[test_syscall exists $s]} {lappend syscall_list $s} } diff --git a/test/wal2.test b/test/wal2.test index c7f00ea60f..cbefb7ab1e 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1042,7 +1042,10 @@ tvfs delete # if {$::tcl_platform(platform) == "unix"} { faultsim_delete_and_reopen - set umask [exec /bin/sh -c umask] + # Changed on 2012-02-13: umask is deliberately ignored for -wal files. + #set umask [exec /bin/sh -c umask] + set umask 0 + do_test wal2-12.1 { sqlite3 db test.db