]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/unit: delay creating a stack variable until after length has been checked 8461/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 18 Mar 2018 11:51:31 +0000 (12:51 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 18 Mar 2018 20:07:01 +0000 (21:07 +0100)
path_is_normalized() will reject paths longer than 4095 bytes, so it's better
to not create a stack variable of unbounded size, but instead do the check first
and only then do that allocation.

Also use _cleanup_ to make things a bit shorter.

https://oss-fuzz.com/v2/issue/5424177403133952/7000

src/core/unit.c

index 815701ad4e99898b3c4a689727ad32acc5e7f98e..68def7cae410b4cfec85ad4f7cc4cbab1c80361f 100644 (file)
@@ -4561,7 +4561,8 @@ int unit_kill_context(
 }
 
 int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) {
-        char prefix[strlen(path) + 1], *p;
+        _cleanup_free_ char *p = NULL;
+        char *prefix;
         UnitDependencyInfo di;
         int r;
 
@@ -4584,34 +4585,30 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
         if (!p)
                 return -ENOMEM;
 
-        path_kill_slashes(p);
+        path = path_kill_slashes(p);
 
-        if (!path_is_normalized(p)) {
-                free(p);
+        if (!path_is_normalized(path))
                 return -EPERM;
-        }
 
-        if (hashmap_contains(u->requires_mounts_for, p)) {
-                free(p);
+        if (hashmap_contains(u->requires_mounts_for, path))
                 return 0;
-        }
 
         di = (UnitDependencyInfo) {
                 .origin_mask = mask
         };
 
-        r = hashmap_put(u->requires_mounts_for, p, di.data);
-        if (r < 0) {
-                free(p);
+        r = hashmap_put(u->requires_mounts_for, path, di.data);
+        if (r < 0)
                 return r;
-        }
+        p = NULL;
 
-        PATH_FOREACH_PREFIX_MORE(prefix, p) {
+        prefix = alloca(strlen(path) + 1);
+        PATH_FOREACH_PREFIX_MORE(prefix, path) {
                 Set *x;
 
                 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
                 if (!x) {
-                        char *q;
+                        _cleanup_free_ char *q = NULL;
 
                         r = hashmap_ensure_allocated(&u->manager->units_requiring_mounts_for, &path_hash_ops);
                         if (r < 0)
@@ -4622,17 +4619,15 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask)
                                 return -ENOMEM;
 
                         x = set_new(NULL);
-                        if (!x) {
-                                free(q);
+                        if (!x)
                                 return -ENOMEM;
-                        }
 
                         r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
                         if (r < 0) {
-                                free(q);
                                 set_free(x);
                                 return r;
                         }
+                        q = NULL;
                 }
 
                 r = set_put(x, u);