]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: fix TOCTOU in cg_chmod_path()
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Wed, 24 Aug 2022 18:49:03 +0000 (12:49 -0600)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 24 Aug 2022 18:49:25 +0000 (12:49 -0600)
Fix TOCTOU warning, reported by Coverity Tool:

CID 258267 (#1 of 1): Time of check time of use (TOCTOU).
fs_check_call: Calling function stat to perform check on path.

in cg_chmod_path(), the file name is stat() and not immediately followed
by the file operation. One way to fix it, open the file and use the file
descriptor to manipulate the file.

Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
(cherry picked from commit 8b9665c29cb812c255687d6e5cb5262a6fe30a40)

src/api.c

index 6feff3a56acb778fb1444f62f93774a935f2abe1..9589bad71d5154e73dddb5d249ad87f144310ac4 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -205,17 +205,21 @@ int cg_chmod_path(const char *path, mode_t mode, int owner_is_umask)
 {
        struct stat buf;
        mode_t mask = -1U;
+       int fd;
 
        if (owner_is_umask) {
                mode_t umask, gmask, omask;
 
+               fd = open(path, O_RDONLY);
+               if (fd == -1)
+                       goto fail;
                /*
                 * Use owner permissions as an umask for group and others
                 * permissions because we trust kernel to initialize owner
                 * permissions to something useful.
                 * Keep SUID and SGID bits.
                 */
-               if (stat(path, &buf) == -1)
+               if (fstat(fd, &buf) == -1)
                        goto fail;
                umask = S_IRWXU & buf.st_mode;
                gmask = umask >> 3;
@@ -224,15 +228,21 @@ int cg_chmod_path(const char *path, mode_t mode, int owner_is_umask)
                mask = umask|gmask|omask|S_ISUID|S_ISGID|S_ISVTX;
        }
 
-       if (chmod(path, mode & mask))
+       if (fchmod(fd, mode & mask))
                goto fail;
 
+       close (fd);
+
        return 0;
 
 fail:
        cgroup_warn("Warning: cannot change permissions of file %s: %s\n", path,
                        strerror(errno));
        last_errno = errno;
+
+       if (fd > 0)
+               close(fd);
+
        return ECGOTHER;
 }