[Tarantool-patches] [PATCH v3 1/2] sql: add missing diag_set on failure when working inside os_unix.c

Leonid Vasiliev lvasiliev at tarantool.org
Thu Dec 17 02:09:06 MSK 2020


SQL module didn't set an error in the diagnostics area on failure
inside unix.c. This could lead to a crash like in #5537.

Co-authored-by: Mergen Imeev<imeevma at gmail.com>

Follow-up #5537
---
 src/box/sql/os_unix.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 5 deletions(-)

diff --git a/src/box/sql/os_unix.c b/src/box/sql/os_unix.c
index d64f1bd..4f59767 100644
--- a/src/box/sql/os_unix.c
+++ b/src/box/sql/os_unix.c
@@ -159,14 +159,17 @@ robust_open(const char *z, int f, mode_t m)
 		if (fd < 0) {
 			if (errno == EINTR)
 				continue;
+			diag_set(SystemError, "failed to open file '%s'", z);
 			break;
 		}
 		if (fd >= SQL_MINIMUM_FILE_DESCRIPTOR)
 			break;
 		close(fd);
 		fd = -1;
-		if (open("/dev/null", f, m) < 0)
+		if (open("/dev/null", f, m) < 0) {
+			diag_set(SystemError, "failed to open '/dev/null'");
 			break;
+		}
 	}
 	if (fd >= 0) {
 		if (m != 0) {
@@ -193,6 +196,10 @@ robust_ftruncate(int h, sql_int64 sz)
 	do {
 		rc = ftruncate(h, sz);
 	} while (rc < 0 && errno == EINTR);
+
+	if (rc < 0)
+		diag_set(SystemError, "failed to truncate file");
+
 	return rc;
 }
 
@@ -395,6 +402,9 @@ findInodeInfo(unixFile * pFile,	/* Unix file with file desc used in the key */
 	fd = pFile->h;
 	rc = fstat(fd, &statbuf);
 	if (rc != 0) {
+		diag_set(SystemError,
+			 "failed to retrive information about the file '%s'",
+			 pFile->zPath);
 		storeLastErrno(pFile, errno);
 		return -1;
 	}
@@ -433,7 +443,13 @@ static int
 fileHasMoved(unixFile * pFile)
 {
 	struct stat buf;
-	return pFile->pInode != NULL && (stat(pFile->zPath, &buf) != 0 ||
+	int rc = stat(pFile->zPath, &buf);
+	if (rc < 0) {
+		diag_set(SystemError,
+			 "failed to retrive information about the file '%s'",
+			 pFile->zPath);
+	}
+	return pFile->pInode != NULL && (rc != 0 ||
 					 (u64) buf.st_ino !=
 					 pFile->pInode->fileId.ino);
 }
@@ -473,8 +489,12 @@ unixFileLock(unixFile * pFile, struct flock *pLock)
 			lock.l_len = SHARED_SIZE;
 			lock.l_type = F_WRLCK;
 			rc = fcntl(pFile->h, F_SETLK, &lock);
-			if (rc < 0)
+			if (rc < 0) {
+				diag_set(SystemError,
+					 "failed to acquire a lock on the"
+					 " file '%s'", pFile->zPath);
 				return rc;
+			}
 			pInode->bProcessLock = 1;
 			pInode->nLock++;
 		} else {
@@ -482,6 +502,11 @@ unixFileLock(unixFile * pFile, struct flock *pLock)
 		}
 	} else {
 		rc = fcntl(pFile->h, F_SETLK, pLock);
+		if (rc < 0) {
+			diag_set(SystemError,
+				 "failed to acquire a lock on the file '%s'",
+				 pFile->zPath);
+		}
 	}
 	return rc;
 }
@@ -729,6 +754,9 @@ seekAndRead(unixFile * id, sql_int64 offset, void *pBuf, int cnt)
 	do {
 		newOffset = lseek(id->h, offset, SEEK_SET);
 		if (newOffset < 0) {
+			diag_set(SystemError,
+				 "failed to reposition the offset of '%s' file",
+				 id->zPath);
 			storeLastErrno((unixFile *) id, errno);
 			return -1;
 		}
@@ -740,6 +768,8 @@ seekAndRead(unixFile * id, sql_int64 offset, void *pBuf, int cnt)
 				got = 1;
 				continue;
 			}
+			diag_set(SystemError, "failed to read from file '%s'",
+				 id->zPath);
 			prior = 0;
 			storeLastErrno((unixFile *) id, errno);
 			break;
@@ -825,10 +855,16 @@ seekAndWriteFd(int fd,		/* File descriptor to write to */
 	do {
 		i64 iSeek = lseek(fd, iOff, SEEK_SET);
 		if (iSeek < 0) {
+			diag_set(SystemError,
+				 "failed to reposition file offset");
 			rc = -1;
 			break;
 		}
 		rc = write(fd, pBuf, nBuf);
+		if (rc < 0) {
+			diag_set(SystemError,
+				 "failed to write %i bytes to file", nBuf);
+		}
 	} while (rc < 0 && errno == EINTR);
 
 	if (rc < 0)
@@ -940,8 +976,12 @@ fcntlSizeHint(unixFile * pFile, i64 nByte)
 		i64 nSize;	/* Required file size */
 		struct stat buf;	/* Used to hold return values of fstat() */
 
-		if (fstat(pFile->h, &buf))
+		if (fstat(pFile->h, &buf)) {
+			diag_set(SystemError,
+				 "failed to retrive information about the"
+				 " file '%s'", pFile->zPath);
 			return -1;
+		}
 
 		nSize =
 		    ((nByte + pFile->szChunk -
@@ -1165,8 +1205,12 @@ unixMapfile(unixFile * pFd, i64 nMap)
 
 	if (nMap < 0) {
 		struct stat statbuf;	/* Low-level file information */
-		if (fstat(pFd->h, &statbuf))
+		if (fstat(pFd->h, &statbuf)) {
+			diag_set(SystemError,
+				 "failed to retrive information about the"
+				 " file '%s'", pFd->zPath);
 			return -1;
+		}
 		nMap = statbuf.st_size;
 	}
 	if (nMap > pFd->mmapSizeMax) {
@@ -1449,6 +1493,8 @@ unixTempFileDir(void)
 			break;
 		zDir = azDirs[i++];
 	}
+	diag_set(ClientError, ER_SYSTEM,
+		 "No access to any temporary directory");
 	return 0;
 }
 
@@ -1558,6 +1604,9 @@ getFileMode(const char *zFile,	/* File name */
 		*pUid = sStat.st_uid;
 		*pGid = sStat.st_gid;
 	} else {
+		diag_set(SystemError,
+			 "failed to retrive information about the file '%s'",
+			 zFile);
 		rc = -1;
 	}
 	return rc;
@@ -1813,6 +1862,7 @@ unixDelete(sql_vfs * NotUsed,	/* VFS containing this as the xDelete method */
 	int rc = 0;
 	UNUSED_PARAMETER(NotUsed);
 	if (unlink(zPath) == (-1)) {
+		diag_set(SystemError, "failed to unlink the file '%s'", zPath);
 		return -1;
 	}
 	if ((dirSync & 1) != 0) {
@@ -1821,6 +1871,9 @@ unixDelete(sql_vfs * NotUsed,	/* VFS containing this as the xDelete method */
 		if (rc == 0) {
 			struct stat buf;
 			if (fstat(fd, &buf)) {
+				diag_set(SystemError,
+					 "failed to retrive information about"
+					 " the file '%s'", zPath);
 				rc = -1;
 			}
 			close(fd);
-- 
2.7.4



More information about the Tarantool-patches mailing list