summaryrefslogtreecommitdiffstats
path: root/src/shared/specifier.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-05-09 18:46:48 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-05-12 03:26:07 +0200
commit065364920281e1cf59cab989e17aff21790505c4 (patch)
treeeb7c2c1045de0b868d706a1b68d6d3e4e0aac394 /src/shared/specifier.c
parentdns-domain: use DNS_LABEL_MAX at one more place (diff)
downloadsystemd-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.c13
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 */