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]);
        }

Reply via email to