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.

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.
check-in: d9c018f8 user: drh tags: trunk

Make the unix VFS defensive against the error of having a database file open
on file descriptors 1 or 2, as an error message might easily be written onto
those file descriptors and thus overwrite and corrupt the database.
check-in: 30d38cc4 user: drh tags: trunk

}
for(i++; i<ArraySize(aSyscall); i++){
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*** 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.
**
** 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
................................................................................
** 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, mode_t m){
int fd;
mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
do{
#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( m!=0 ){
struct stat statbuf;
if( osFstat(fd, &statbuf)==0
&& statbuf.st_size==0
&& (statbuf.st_mode&0777)!=m
){