aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-08-30 06:20:23 +0000
committerdrh <drh@noemail.net>2013-08-30 06:20:23 +0000
commit5128d009c6259bc2c0d7ef9dd99da368c43c08e8 (patch)
tree220f0d88a1d80c876ade5b220951869405d08235 /src/os_unix.c
parent00ea0e113340444e9a1dceb6c7246b2aea242511 (diff)
downloadsqlite-5128d009c6259bc2c0d7ef9dd99da368c43c08e8.tar.gz
sqlite-5128d009c6259bc2c0d7ef9dd99da368c43c08e8.zip
Improvements to the robust_open() logic in the unix VFS so that if an attempt
is made to open a repository on file descriptors 0, 1, or 2, and blocking that file descriptor by opening it on /dev/null fails, then the open will fail. FossilOrigin-Name: d9c018f8155ab48df8e0e02519bba50588fe49fc
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c39
1 files changed, 12 insertions, 27 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index a90c8eede..8688a652f 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -552,31 +552,6 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
}
/*
-** If fd is a file descriptor that would be dangerous to use for an
-** ordinary file, the close it, reopen it as /dev/null to get it out
-** of the way, then return true.
-**
-** If fd is safe, return 0.
-**
-** It is dangerous to have a database file open of file descriptors 1 or
-** 2 because those normally mean standard output and standard error. Other
-** components of the system might write directly to those file descriptors
-** and overwrite parts of the database file. Something like this happened
-** on 2013-08-29 to the canonical Fossil repository when some error caused
-** the database file to be opened on file descriptor 2 and later an assert()
-** fired and wrote error message text into file descriptor 2, corrupting
-** the repository.
-*/
-static int isReservedFd(int fd, const char *z, int f, int m){
- if( fd<0 || fd>2 ) return 0;
- sqlite3_log(SQLITE_WARNING,
- "attempt to open \"%s\" as file descriptor %d", z, fd);
- osClose(fd);
- (void)osOpen("/dev/null",f,m);
- return 1;
-}
-
-/*
** Invoke open(). Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
@@ -596,13 +571,23 @@ static int isReservedFd(int fd, const char *z, int f, int m){
static int robust_open(const char *z, int f, mode_t m){
int fd;
mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
- do{
+ while(1){
#if defined(O_CLOEXEC)
fd = osOpen(z,f|O_CLOEXEC,m2);
#else
fd = osOpen(z,f,m2);
#endif
- }while( (fd<0 && errno==EINTR) || isReservedFd(fd,z,f,m2) );
+ if( fd<0 ){
+ if( errno==EINTR ) continue;
+ break;
+ }
+ if( fd>2 ) break;
+ osClose(fd);
+ sqlite3_log(SQLITE_WARNING,
+ "attempt to open \"%s\" as file descriptor %d", z, fd);
+ fd = -1;
+ if( osOpen("/dev/null", f, m)<0 ) break;
+ }
if( fd>=0 ){
if( m!=0 ){
struct stat statbuf;