commit: 982ea6b9dcea2a86d3772c99cff9ada0c400bf29
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 26 19:30:45 2020 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Jan 26 19:30:45 2020 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=982ea6b9
libq/xpak: fix Coverity 125939 Time of check time of use
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/xpak.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/libq/xpak.c b/libq/xpak.c
index 90a3570..59c541d 100644
--- a/libq/xpak.c
+++ b/libq/xpak.c
@@ -223,7 +223,7 @@ xpak_process(
static void
_xpak_add_file(
- int dir_fd,
+ int fd,
const char *filename,
struct stat *st,
FILE *findex,
@@ -236,7 +236,7 @@ _xpak_add_file(
unsigned char intbuf[4];
unsigned char *p = intbuf;
const char *basefile;
- int fd, in_len;
+ int in_len;
basefile = basename(filename);
@@ -259,28 +259,24 @@ _xpak_add_file(
/* now open the file, get (data_len),
* and append the file to the data file */
- fd = openat(dir_fd, filename, O_RDONLY|O_CLOEXEC);
- if (fd < 0) {
- open_fail:
+ if ((fin = fdopen(fd, "r")) == NULL) {
warnp("could not open for reading: %s", filename);
- fake_data_len:
WRITE_BE_INT32(p, 0);
fwrite(p, 1, 4, findex);
return;
}
- fin = fdopen(fd, "r");
- if (!fin) {
- close(fd);
- goto open_fail;
- }
+
in_len = st->st_size;
/* the xpak format can only store files whose size is a 32bit int
* so we have to make sure we don't store a big file */
if (in_len != st->st_size) {
warnf("File is too big: %zu", (size_t)st->st_size);
fclose(fin);
- goto fake_data_len;
+ WRITE_BE_INT32(p, 0);
+ fwrite(p, 1, 4, findex);
+ return;
}
+
WRITE_BE_INT32(p, in_len);
fwrite(p, 1, 4, findex);
copy_file(fin, fdata);
@@ -333,6 +329,8 @@ xpak_create(
index_len = data_len = 0;
for (i = 0; i < argc; ++i) {
+ int fd;
+
if (fstatat(dir_fd, argv[i], &st, 0)) {
warnp("fstatat(%s) failed", argv[i]);
continue;
@@ -344,22 +342,32 @@ xpak_create(
for (fidx = 0; fidx < numfiles; ++fidx) {
int ret = snprintf(path, sizeof(path), "%s/%s",
argv[i], dir[fidx]->d_name);
+
if (ret < 0 || (size_t)ret >= sizeof(path)) {
warn("skipping path too long: %s/%s",
argv[i],
dir[fidx]->d_name);
continue;
}
- if (stat(path, &st) < 0) {
+
+ fd = openat(dir_fd, path, O_RDONLY|O_CLOEXEC);
+ if (fd < 0 || fstat(fd, &st) < 0) {
warnp("could not read %s", path);
continue;
}
- _xpak_add_file(dir_fd, path, &st,
+ _xpak_add_file(fd, path, &st,
findex, &index_len, fdata,
&data_len, verbose);
+ close(fd);
}
scandir_free(dir, numfiles);
} else if (S_ISREG(st.st_mode)) {
- _xpak_add_file(dir_fd, argv[i], &st,
+ fd = openat(dir_fd, argv[i], O_RDONLY|O_CLOEXEC);
+ if (fd < 0 || fstat(fd, &st) < 0) {
+ warnp("could not read %s", path);
+ continue;
+ }
+ _xpak_add_file(fd, argv[i], &st,
findex, &index_len, fdata, &data_len,
verbose);
+ close(fd);
} else
warn("Skipping non file/directory '%s'", argv[i]);
}