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

shared/specifier: be less extravagant with memory allocations

ubsan times out because we do too many allocations:

$ valgrind build/fuzz-unit-file test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-full
...
test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-full... ok
==1757==
==1757== HEAP SUMMARY:
==1757==     in use at exit: 0 bytes in 0 blocks
==1757==   total heap usage: 199,997 allocs, 199,997 frees, 90,045,318,585 bytes allocated

...
==3256==   total heap usage: 100,120 allocs, 100,120 frees, 13,097,140 bytes allocated

https://oss-fuzz.com/v2/issue/4651449704251392/6977 should now be really fixed.

e3c3d6761b was the first attempt, but even with this change, e3c3d6761b
still makes sense.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-03-28 10:15:44 +02:00
parent 27fe58b77b
commit e2093454a2
2 changed files with 8 additions and 15 deletions

View File

@ -46,7 +46,7 @@
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
size_t l;
size_t l, allocated = 0;
_cleanup_free_ char *ret = NULL;
char *t;
const char *f;
@ -57,14 +57,11 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
assert(table);
l = strlen(text);
ret = new(char, l+1);
if (!ret)
if (!GREEDY_REALLOC(ret, allocated, l + 1))
return -ENOMEM;
t = ret;
for (f = text; *f; f++, l--) {
for (f = text; *f; f++, l--)
if (percent) {
if (*f == '%')
*(t++) = '%';
@ -77,7 +74,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
if (i->lookup) {
_cleanup_free_ char *w = NULL;
char *n;
size_t k, j;
r = i->lookup(i->specifier, i->data, userdata, &w);
@ -87,14 +83,9 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
j = t - ret;
k = strlen(w);
n = new(char, j + k + l + 1);
if (!n)
if (!GREEDY_REALLOC(ret, allocated, j + k + l + 1))
return -ENOMEM;
memcpy(n, ret, j);
memcpy(n + j, w, k);
free_and_replace(ret, n);
memcpy(ret + j, w, k);
t = ret + j + k;
} else if (strchr(POSSIBLE_SPECIFIERS, *f))
/* Oops, an unknown specifier. */
@ -110,7 +101,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
percent = true;
else
*(t++) = *f;
}
/* if string ended with a stray %, also end with % */
if (percent)

File diff suppressed because one or more lines are too long