From ca8700e922e280beeb3c5f37a967c21739da0f25 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 18 Mar 2018 12:51:31 +0100 Subject: [PATCH] core/unit: delay creating a stack variable until after length has been checked 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 | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 815701ad4e9..68def7cae41 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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); -- 2.47.3