diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-09-14 20:33:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-14 20:33:12 +0200 |
commit | d97c672be0aa06f9e2ef3543b6d1346eadee7bc8 (patch) | |
tree | ea7e9afb5a72c12271c4cacbbf16ef978dea8c8c /src/shared | |
parent | Add HUAWEI MateBook D 15 AMD ACCEL properties (diff) | |
parent | dns-domain: add test case from #34399 (diff) | |
download | systemd-d97c672be0aa06f9e2ef3543b6d1346eadee7bc8.tar.xz systemd-d97c672be0aa06f9e2ef3543b6d1346eadee7bc8.zip |
Merge pull request #34405 from poettering/dns-domain-validate-fix
dns-domain: fix validation check for max name
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/dns-domain.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index ba24a77dad..3635167b33 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -395,9 +395,9 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, } #endif -int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) { - _cleanup_free_ char *ret = NULL; - size_t n = 0; +int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret) { + _cleanup_free_ char *result = NULL; + size_t n_result = 0, n_unescaped = 0; const char *p; bool first = true; int r; @@ -427,17 +427,18 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r break; } + n_unescaped += r + !first; /* Count unescaped length to make max length determination below */ - if (_ret) { - if (!GREEDY_REALLOC(ret, n + !first + DNS_LABEL_ESCAPED_MAX)) + if (ret) { + if (!GREEDY_REALLOC(result, n_result + !first + DNS_LABEL_ESCAPED_MAX)) return -ENOMEM; - r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX); + r = dns_label_escape(label, r, result + n_result + !first, DNS_LABEL_ESCAPED_MAX); if (r < 0) return r; if (!first) - ret[n] = '.'; + result[n_result] = '.'; } else { char escaped[DNS_LABEL_ESCAPED_MAX]; @@ -446,28 +447,34 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r return r; } - n += r + !first; + n_result += r + !first; first = false; } finish: - if (n > DNS_HOSTNAME_MAX) - return -EINVAL; + if (n_unescaped == 0) { + /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */ - if (_ret) { - if (n == 0) { - /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */ - if (!GREEDY_REALLOC(ret, 2)) + if (ret) { + if (!GREEDY_REALLOC(result, 2)) /* Room for dot, and already pre-allocate space for the trailing NUL byte at the same time */ return -ENOMEM; - ret[n++] = '.'; - } else { - if (!GREEDY_REALLOC(ret, n + 1)) - return -ENOMEM; + result[n_result++] = '.'; } - ret[n] = 0; - *_ret = TAKE_PTR(ret); + n_unescaped++; + } + + if (n_unescaped > DNS_HOSTNAME_MAX) /* Enforce max length check on unescaped length */ + return -EINVAL; + + if (ret) { + /* Suffix with a NUL byte */ + if (!GREEDY_REALLOC(result, n_result + 1)) + return -ENOMEM; + + result[n_result] = 0; + *ret = TAKE_PTR(result); } return 0; |