summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-09-14 20:33:12 +0200
committerGitHub <noreply@github.com>2024-09-14 20:33:12 +0200
commitd97c672be0aa06f9e2ef3543b6d1346eadee7bc8 (patch)
treeea7e9afb5a72c12271c4cacbbf16ef978dea8c8c /src/shared
parentAdd HUAWEI MateBook D 15 AMD ACCEL properties (diff)
parentdns-domain: add test case from #34399 (diff)
downloadsystemd-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.c47
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;