]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
src/api.c fix TOCTOU in cg_mkdir_p()
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Mon, 17 Jul 2023 09:08:19 +0000 (14:38 +0530)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 19 Jul 2023 02:58:46 +0000 (20:58 -0600)
Fix a TOCTOU issue, reported by Coverity tool:

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

Add new switch for EROFS, to explicitly check if the file exist on
mkdir()'s error path, using a new char pointer.

Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
src/api.c

index 72d44b9e0a0ee20e44b354dd4ee44ef34e47946e..46842164320e6113f795e45c9f24c511828a6d60 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -2109,8 +2109,9 @@ int cgroup_attach_task(struct cgroup *cgroup)
 int cg_mkdir_p(const char *path)
 {
        char *real_path = NULL;
-       int stat_ret, ret = 0;
+       char *tmp_path = NULL;
        struct stat st;
+       int ret = 0;
        int i = 0;
        char pos;
 
@@ -2135,7 +2136,6 @@ int cg_mkdir_p(const char *path)
 
                /* 0775 == S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH */
                ret = mkdir(real_path, 0775);
-               real_path[i] = pos;
                if (ret) {
                        switch (errno) {
                        case EEXIST:
@@ -2144,19 +2144,21 @@ int cg_mkdir_p(const char *path)
                        case EPERM:
                                ret = ECGROUPNOTOWNER;
                                goto done;
-                       default:
-                               /* Check if path exists */
-                               real_path[i] = '\0';
-                               stat_ret = stat(real_path, &st);
-                               real_path[i] = pos;
-                               if (stat_ret == 0) {
-                                       ret = 0;        /* Path exists */
-                                       break;
-                               }
+                       case EROFS:
+                               /*
+                                * Check if path exists, use tmp_path to
+                                * keep Coverity happy
+                                */
+                               tmp_path = real_path;
+                               ret = stat(tmp_path, &st);
+                               if (ret == 0)
+                                       break;  /* Path exists */
+                       default: /* fallthrough */
                                ret = ECGROUPNOTALLOWED;
                                goto done;
                        }
                }
+               real_path[i] = pos;
        } while (real_path[i]);
 
 done: