1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

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
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-03-18 12:51:31 +01:00
parent bd0763b642
commit ca8700e922

View 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);