diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-09 18:46:48 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-12 03:26:07 +0200 |
commit | 065364920281e1cf59cab989e17aff21790505c4 (patch) | |
tree | eb7c2c1045de0b868d706a1b68d6d3e4e0aac394 /src/shared/specifier.c | |
parent | dns-domain: use DNS_LABEL_MAX at one more place (diff) | |
download | systemd-065364920281e1cf59cab989e17aff21790505c4.tar.xz systemd-065364920281e1cf59cab989e17aff21790505c4.zip |
tree-wide: refuse too long strings earlier in specifier_printf()
We usually call specifier_printf() and then check the validity of
the result. In many cases, validity checkers, e.g. path_is_valid(),
refuse too long strings. This makes specifier_printf() refuse such
long results earlier.
Moreover, unit_full_string() and description field in sysuser now
refuse results longer than LONG_LINE_MAX. config_parse() already
refuses the line longer than LONG_LINE_MAX. Hence, it should be ok
to set the same value as the maximum length of the resolved string.
Diffstat (limited to 'src/shared/specifier.c')
-rw-r--r-- | src/shared/specifier.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/shared/specifier.c b/src/shared/specifier.c index dc86b04b83..ef164b3942 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -29,7 +29,7 @@ * and "%" used for escaping. */ #define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%" -int specifier_printf(const char *text, const Specifier table[], const void *userdata, char **ret) { +int specifier_printf(const char *text, size_t max_length, const Specifier table[], const void *userdata, char **ret) { size_t l, allocated = 0; _cleanup_free_ char *result = NULL; char *t; @@ -45,7 +45,7 @@ int specifier_printf(const char *text, const Specifier table[], const void *user return -ENOMEM; t = result; - for (f = text; *f; f++, l--) + for (f = text; *f != '\0'; f++, l--) { if (percent) { if (*f == '%') *(t++) = '%'; @@ -86,9 +86,16 @@ int specifier_printf(const char *text, const Specifier table[], const void *user else *(t++) = *f; + if ((size_t) (t - result) > max_length) + return -ENAMETOOLONG; + } + /* If string ended with a stray %, also end with % */ - if (percent) + if (percent) { *(t++) = '%'; + if ((size_t) (t - result) > max_length) + return -ENAMETOOLONG; + } *(t++) = 0; /* Try to deallocate unused bytes, but don't sweat it too much */ |