1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-04 21:47:31 +03:00

Merge pull request #34405 from poettering/dns-domain-validate-fix

dns-domain: fix validation check for max name
This commit is contained in:
Yu Watanabe 2024-09-15 03:33:12 +09:00 committed by GitHub
commit d97c672be0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 20 deletions

View File

@ -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;

View File

@ -375,6 +375,9 @@ static void test_dns_name_is_valid_one(const char *s, int ret, int ret_ldh) {
}
TEST(dns_name_is_valid) {
test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[._qotd._tcp.local", 1, 0);
test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]._qotd._tcp.local", 0, 0);
test_dns_name_is_valid_one("foo", 1, 1);
test_dns_name_is_valid_one("foo.", 1, 1);
test_dns_name_is_valid_one("foo..", 0, 0);