Merge pull request #974 from terrelln/dstfile

[fileio] Improve safety of output file modifications
This commit is contained in:
Yann Collet 2018-01-10 19:02:48 +01:00 committed by GitHub
commit 1edf33764e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 9 deletions

View File

@ -139,7 +139,10 @@ static void INThandler(int sig)
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
signal(sig, SIG_IGN); /* this invocation generates a buggy warning in Visual Studio */ signal(sig, SIG_IGN); /* this invocation generates a buggy warning in Visual Studio */
#endif #endif
if (g_artefact) remove(g_artefact); if (g_artefact) {
assert(UTIL_isRegularFile(g_artefact));
remove(g_artefact);
}
DISPLAY("\n"); DISPLAY("\n");
exit(2); exit(2);
} }
@ -861,7 +864,7 @@ static int FIO_compressFilename_srcFile(cRess_t ress,
* delete both the source and destination files. * delete both the source and destination files.
*/ */
clearHandler(); clearHandler();
if (remove(srcFileName)) if (FIO_remove(srcFileName))
EXM_THROW(1, "zstd: %s: %s", srcFileName, strerror(errno)); EXM_THROW(1, "zstd: %s: %s", srcFileName, strerror(errno));
} }
return result; return result;
@ -898,11 +901,13 @@ static int FIO_compressFilename_dstFile(cRess_t ress,
DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
result=1; result=1;
} }
if (result!=0) { /* remove operation artefact */ if ( (result != 0) /* operation failure */
if (remove(dstFileName)) && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null */
EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); && strcmp(dstFileName, stdoutmark) ) /* special case : don't remove() stdout */
} FIO_remove(dstFileName); /* remove compression artefact; note don't do anything special if remove() fails */
else if (strcmp (dstFileName, stdoutmark) && stat_result) else if ( strcmp(dstFileName, stdoutmark)
&& strcmp(dstFileName, nulmark)
&& stat_result)
UTIL_setFileStat(dstFileName, &statbuf); UTIL_setFileStat(dstFileName, &statbuf);
return result; return result;
@ -1575,7 +1580,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch
* delete both the source and destination files. * delete both the source and destination files.
*/ */
clearHandler(); clearHandler();
if (remove(srcFileName)) { if (FIO_remove(srcFileName)) {
/* failed to remove src file */ /* failed to remove src file */
DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno)); DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno));
return 1; return 1;
@ -1618,7 +1623,7 @@ static int FIO_decompressDstFile(dRess_t ress,
if ( (result != 0) /* operation failure */ if ( (result != 0) /* operation failure */
&& strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */ && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */
&& strcmp(dstFileName, stdoutmark) ) /* special case : don't remove() stdout */ && strcmp(dstFileName, stdoutmark) ) /* special case : don't remove() stdout */
remove(dstFileName); /* remove decompression artefact; note don't do anything special if remove() fails */ FIO_remove(dstFileName); /* remove decompression artefact; note don't do anything special if remove() fails */
else { /* operation success */ else { /* operation success */
if ( strcmp(dstFileName, stdoutmark) /* special case : don't chmod stdout */ if ( strcmp(dstFileName, stdoutmark) /* special case : don't chmod stdout */
&& strcmp(dstFileName, nulmark) /* special case : don't chmod /dev/null */ && strcmp(dstFileName, nulmark) /* special case : don't chmod /dev/null */

View File

@ -246,11 +246,17 @@ UTIL_STATIC void UTIL_waitForNextTick(void)
#endif #endif
UTIL_STATIC int UTIL_isRegularFile(const char* infilename);
UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf) UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf)
{ {
int res = 0; int res = 0;
struct utimbuf timebuf; struct utimbuf timebuf;
if (!UTIL_isRegularFile(filename))
return -1;
timebuf.actime = time(NULL); timebuf.actime = time(NULL);
timebuf.modtime = statbuf->st_mtime; timebuf.modtime = statbuf->st_mtime;
res += utime(filename, &timebuf); /* set access and modification times */ res += utime(filename, &timebuf); /* set access and modification times */