Fix TOCTOU race conditions reported by CodeQL and Coverity
CodeQL and Coverity both complained about: * lib/libshare/os/linux/smb.c * tests/zfs-tests/cmd/mmapwrite.c * twice * tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c * tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c * coverity had a second complaint that CodeQL did not have * tests/zfs-tests/cmd/suid_write_to_file.c * Coverity had two complaints and CodeQL had one complaint, both differed. The CodeQL complaint is about the main point of the test, so it is not fixable without a hack involving `fork()`. The issues reported by CodeQL are fixed, with the exception of the last one, which is deemed to be a false positive that is too much trouble to wrokaround. The issues reported by Coverity were only fixed if CodeQL complained about them. There were issues reported by Coverity in a number of other files that were not reported by CodeQL, but fixing the CodeQL complaints is considered a priority since we want to integrate it into a github workflow, so the remaining Coverity complaints are left for future work. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Closes #14098
This commit is contained in:
parent
82ad2a06ac
commit
4170ae4ea6
|
@ -90,21 +90,32 @@ smb_retrieve_shares(void)
|
||||||
|
|
||||||
/* Go through the directory, looking for shares */
|
/* Go through the directory, looking for shares */
|
||||||
while ((directory = readdir(shares_dir))) {
|
while ((directory = readdir(shares_dir))) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (directory->d_name[0] == '.')
|
if (directory->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(file_path, sizeof (file_path),
|
snprintf(file_path, sizeof (file_path),
|
||||||
"%s/%s", SHARE_DIR, directory->d_name);
|
"%s/%s", SHARE_DIR, directory->d_name);
|
||||||
|
|
||||||
if (stat(file_path, &eStat) == -1) {
|
if ((fd = open(file_path, O_RDONLY | O_CLOEXEC)) == -1) {
|
||||||
rc = SA_SYSTEM_ERR;
|
rc = SA_SYSTEM_ERR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISREG(eStat.st_mode))
|
if (stat(file_path, &eStat) == -1) {
|
||||||
continue;
|
close(fd);
|
||||||
|
rc = SA_SYSTEM_ERR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if ((share_file_fp = fopen(file_path, "re")) == NULL) {
|
if (!S_ISREG(eStat.st_mode)) {
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((share_file_fp = fdopen(fd, "r")) == NULL) {
|
||||||
|
close(fd);
|
||||||
rc = SA_SYSTEM_ERR;
|
rc = SA_SYSTEM_ERR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,29 +88,21 @@ map_writer(void *filename)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
int page_size = getpagesize();
|
int page_size = getpagesize();
|
||||||
int op_errno = 0;
|
|
||||||
char *file_path = filename;
|
char *file_path = filename;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = access(file_path, F_OK);
|
fd = open(file_path, O_RDWR);
|
||||||
if (ret) {
|
if (fd == -1) {
|
||||||
op_errno = errno;
|
if (errno == ENOENT) {
|
||||||
if (op_errno == ENOENT) {
|
|
||||||
fd = open(file_path, O_RDWR | O_CREAT, 0777);
|
fd = open(file_path, O_RDWR | O_CREAT, 0777);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
err(1, "open file failed");
|
err(1, "open file failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ftruncate(fd, page_size);
|
ret = ftruncate(fd, page_size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
err(1, "truncate file failed");
|
err(1, "truncate file failed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err(1, "access file failed!");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fd = open(file_path, O_RDWR, 0777);
|
|
||||||
if (fd == -1) {
|
|
||||||
err(1, "open file failed");
|
err(1, "open file failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ main(void)
|
||||||
int i, fd;
|
int i, fd;
|
||||||
char spath[1024], dpath[1024];
|
char spath[1024], dpath[1024];
|
||||||
const char *penv[] = {"TESTDIR", "TESTFILE0"};
|
const char *penv[] = {"TESTDIR", "TESTFILE0"};
|
||||||
struct stat sbuf;
|
|
||||||
|
|
||||||
(void) fprintf(stdout, "Verify O_TMPFILE file can be linked.\n");
|
(void) fprintf(stdout, "Verify O_TMPFILE file can be linked.\n");
|
||||||
|
|
||||||
|
@ -73,12 +72,10 @@ main(void)
|
||||||
run("export");
|
run("export");
|
||||||
run("import");
|
run("import");
|
||||||
|
|
||||||
if (stat(dpath, &sbuf) < 0) {
|
if (unlink(dpath) == -1) {
|
||||||
perror("stat");
|
perror("unlink");
|
||||||
unlink(dpath);
|
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
unlink(dpath);
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
static void
|
static void
|
||||||
test_stat_mode(mode_t mask)
|
test_stat_mode(mode_t mask)
|
||||||
{
|
{
|
||||||
struct stat st, fst;
|
struct stat fst;
|
||||||
int i, fd;
|
int i, fd;
|
||||||
char spath[1024], dpath[1024];
|
char spath[1024], dpath[1024];
|
||||||
const char *penv[] = {"TESTDIR", "TESTFILE0"};
|
const char *penv[] = {"TESTDIR", "TESTFILE0"};
|
||||||
|
@ -68,7 +68,7 @@ test_stat_mode(mode_t mask)
|
||||||
err(2, "open(%s)", penv[0]);
|
err(2, "open(%s)", penv[0]);
|
||||||
|
|
||||||
if (fstat(fd, &fst) == -1)
|
if (fstat(fd, &fst) == -1)
|
||||||
err(3, "open");
|
err(3, "fstat(%s)", penv[0]);
|
||||||
|
|
||||||
snprintf(spath, sizeof (spath), "/proc/self/fd/%d", fd);
|
snprintf(spath, sizeof (spath), "/proc/self/fd/%d", fd);
|
||||||
snprintf(dpath, sizeof (dpath), "%s/%s", penv[0], penv[1]);
|
snprintf(dpath, sizeof (dpath), "%s/%s", penv[0], penv[1]);
|
||||||
|
@ -78,19 +78,22 @@ test_stat_mode(mode_t mask)
|
||||||
err(4, "linkat");
|
err(4, "linkat");
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (stat(dpath, &st) == -1)
|
/* Verify fstat(2) result at old path */
|
||||||
err(5, "stat");
|
|
||||||
unlink(dpath);
|
|
||||||
|
|
||||||
/* Verify fstat(2) result */
|
|
||||||
mode = fst.st_mode & 0777;
|
mode = fst.st_mode & 0777;
|
||||||
if (mode != masked)
|
if (mode != masked)
|
||||||
errx(6, "fstat(2) %o != %o\n", mode, masked);
|
errx(5, "fstat(2) %o != %o\n", mode, masked);
|
||||||
|
|
||||||
/* Verify stat(2) result */
|
fd = open(dpath, O_RDWR);
|
||||||
mode = st.st_mode & 0777;
|
if (fd == -1)
|
||||||
|
err(6, "open(%s)", dpath);
|
||||||
|
|
||||||
|
if (fstat(fd, &fst) == -1)
|
||||||
|
err(7, "fstat(%s)", dpath);
|
||||||
|
|
||||||
|
/* Verify fstat(2) result at new path */
|
||||||
|
mode = fst.st_mode & 0777;
|
||||||
if (mode != masked)
|
if (mode != masked)
|
||||||
errx(7, "stat(2) %o != %o\n", mode, masked);
|
errx(8, "fstat(2) %o != %o\n", mode, masked);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue