diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-03-28 10:15:44 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-03-28 10:38:45 +0200 |
commit | e2093454a248ff7d879077a77f4e9a086439d353 (patch) | |
tree | a79dd8e551da243f8d37a32ac5f0f50426406729 /src | |
parent | 27fe58b77b5ed322971c7d2ea17ead1518652919 (diff) | |
download | systemd-e2093454a248ff7d879077a77f4e9a086439d353.tar.gz |
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.
e3c3d6761b3e7d was the first attempt, but even with this change, e3c3d6761b3e7d
still makes sense.
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/specifier.c | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/src/shared/specifier.c b/src/shared/specifier.c index 98d95eef8e..c4a3ffd18c 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -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) |