aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-11-22 00:42:01 +0000
committerdrh <drh@noemail.net>2019-11-22 00:42:01 +0000
commitc398c65bee850b6b8f24a44852872a27f114535d (patch)
tree400756f2c2735468faaa02daa969838df2854778 /src/os_unix.c
parentcd30064bd502b9b42a4e0c0e04850f09cefa2617 (diff)
downloadsqlite-c398c65bee850b6b8f24a44852872a27f114535d.tar.gz
sqlite-c398c65bee850b6b8f24a44852872a27f114535d.zip
Revise the SQLITE_OPEN_NOFOLLOW so that it actually uses O_NOFOLLOW in the
open() system call. This backs out the SQLITE_ACCESS_SYMLINK value but adds the new SQLITE_OK_SYMLINK return code from the xFullPathname method of sqlite3_vfs when that routine resolves symbolic links. O_NOFOLLOW is always included in open() system calls for journal files. FossilOrigin-Name: 6a64fb6a2da6c98f1e87b55ad5689967e1db4eae2e08345471d95e28cd567e0f
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 7217a5d5f..18f2afcb6 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3685,7 +3685,7 @@ static int openDirectory(const char *zFilename, int *pFd){
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
@@ -4576,10 +4576,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
+ (sStat.st_mode&0777));
}
if( pShmNode->hShm<0 ){
- pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
+ (sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
@@ -5929,7 +5931,7 @@ static int unixOpen(
unixFile *p = (unixFile *)pFile;
int fd = -1; /* File descriptor returned by open() */
int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int eType = flags&0x0FFF00; /* Type of file to open */
int noLock; /* True to omit locking primitives */
int rc = SQLITE_OK; /* Function Return Code */
int ctrlFlags = 0; /* UNIXFILE_* flags */
@@ -6039,7 +6041,7 @@ static int unixOpen(
if( isReadWrite ) openFlags |= O_RDWR;
if( isCreate ) openFlags |= O_CREAT;
if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY);
+ openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW);
if( fd<0 ){
mode_t openMode; /* Permissions to create file with */
@@ -6251,25 +6253,15 @@ static int unixAccess(
SimulateIOError( return SQLITE_IOERR_ACCESS; );
assert( pResOut!=0 );
- /* The spec says there are four possible values for flags. But the
- ** SQLITE_ACCESS_READ flag is never used */
- assert( flags==SQLITE_ACCESS_EXISTS
- || flags==SQLITE_ACCESS_READWRITE
- || flags==SQLITE_ACCESS_SYMLINK );
+ /* The spec says there are three possible values for flags. But only
+ ** two of them are actually used */
+ assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
if( flags==SQLITE_ACCESS_EXISTS ){
struct stat buf;
*pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
- }else if( flags==SQLITE_ACCESS_READWRITE ){
- *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}else{
-#if !defined(HAVE_LSTAT)
- *pResOut = 0;
-#else
- struct stat buf;
- *pResOut = (0==osLstat(zPath, &buf) && S_ISLNK(buf.st_mode));
-#endif
- assert( flags==SQLITE_ACCESS_SYMLINK );
+ *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
return SQLITE_OK;
}
@@ -6321,7 +6313,7 @@ static int unixFullPathname(
#else
int rc = SQLITE_OK;
int nByte;
- int nLink = 1; /* Number of symbolic links followed so far */
+ int nLink = 0; /* Number of symbolic links followed so far */
const char *zIn = zPath; /* Input path for each iteration of loop */
char *zDel = 0;
@@ -6350,10 +6342,11 @@ static int unixFullPathname(
}
if( bLink ){
+ nLink++;
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
- }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
+ }else if( nLink>=SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
@@ -6389,6 +6382,7 @@ static int unixFullPathname(
}while( rc==SQLITE_OK );
sqlite3_free(zDel);
+ if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
return rc;
#endif /* HAVE_READLINK && HAVE_LSTAT */
}
@@ -6874,7 +6868,7 @@ static int proxyCreateUnixFile(
int fd = -1;
unixFile *pNew;
int rc = SQLITE_OK;
- int openFlags = O_RDWR | O_CREAT;
+ int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW;
sqlite3_vfs dummyVfs;
int terrno = 0;
UnixUnusedFd *pUnused = NULL;
@@ -6904,7 +6898,7 @@ static int proxyCreateUnixFile(
}
}
if( fd<0 ){
- openFlags = O_RDONLY;
+ openFlags = O_RDONLY | O_NOFOLLOW;
fd = robust_open(path, openFlags, 0);
terrno = errno;
}
@@ -7030,7 +7024,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), 0);
+ fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW), 0);
if( fd<0 ){
sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
goto end_breaklock;