mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-08 20:58:20 +03:00
Merge pull request #23707 from yuwata/dns_service_split
dns-domain: fix buffer-overflow
This commit is contained in:
commit
ef55efe823
@ -1022,10 +1022,10 @@ static bool dns_service_name_label_is_valid(const char *label, size_t n) {
|
||||
return dns_service_name_is_valid(s);
|
||||
}
|
||||
|
||||
int dns_service_split(const char *joined, char **_name, char **_type, char **_domain) {
|
||||
int dns_service_split(const char *joined, char **ret_name, char **ret_type, char **ret_domain) {
|
||||
_cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
|
||||
const char *p = joined, *q = NULL, *d = NULL;
|
||||
char a[DNS_LABEL_MAX], b[DNS_LABEL_MAX], c[DNS_LABEL_MAX];
|
||||
const char *p = joined, *q = NULL, *d = joined;
|
||||
char a[DNS_LABEL_MAX+1], b[DNS_LABEL_MAX+1], c[DNS_LABEL_MAX+1];
|
||||
int an, bn, cn, r;
|
||||
unsigned x = 0;
|
||||
|
||||
@ -1045,6 +1045,9 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
|
||||
return bn;
|
||||
|
||||
if (bn > 0) {
|
||||
if (!srv_type_label_is_valid(b, bn))
|
||||
goto finish;
|
||||
|
||||
x++;
|
||||
|
||||
/* If there was a second label, try to get the third one */
|
||||
@ -1053,64 +1056,58 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
|
||||
if (cn < 0)
|
||||
return cn;
|
||||
|
||||
if (cn > 0)
|
||||
if (cn > 0 && srv_type_label_is_valid(c, cn))
|
||||
x++;
|
||||
} else
|
||||
cn = 0;
|
||||
} else
|
||||
an = 0;
|
||||
|
||||
if (x >= 2 && srv_type_label_is_valid(b, bn)) {
|
||||
|
||||
if (x >= 3 && srv_type_label_is_valid(c, cn)) {
|
||||
|
||||
if (dns_service_name_label_is_valid(a, an)) {
|
||||
/* OK, got <name> . <type> . <type2> . <domain> */
|
||||
|
||||
name = strndup(a, an);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
type = strjoin(b, ".", c);
|
||||
if (!type)
|
||||
return -ENOMEM;
|
||||
|
||||
d = p;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
} else if (srv_type_label_is_valid(a, an)) {
|
||||
|
||||
/* OK, got <type> . <type2> . <domain> */
|
||||
|
||||
name = NULL;
|
||||
|
||||
type = strjoin(a, ".", b);
|
||||
if (!type)
|
||||
return -ENOMEM;
|
||||
|
||||
d = q;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
name = NULL;
|
||||
type = NULL;
|
||||
d = joined;
|
||||
switch (x) {
|
||||
case 2:
|
||||
if (!srv_type_label_is_valid(a, an))
|
||||
break;
|
||||
|
||||
/* OK, got <type> . <type2> . <domain> */
|
||||
|
||||
name = NULL;
|
||||
|
||||
type = strjoin(a, ".", b);
|
||||
if (!type)
|
||||
return -ENOMEM;
|
||||
|
||||
d = q;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (!dns_service_name_label_is_valid(a, an))
|
||||
break;
|
||||
|
||||
/* OK, got <name> . <type> . <type2> . <domain> */
|
||||
|
||||
name = strndup(a, an);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
type = strjoin(b, ".", c);
|
||||
if (!type)
|
||||
return -ENOMEM;
|
||||
|
||||
d = p;
|
||||
break;
|
||||
}
|
||||
|
||||
finish:
|
||||
r = dns_name_normalize(d, 0, &domain);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (_domain)
|
||||
*_domain = TAKE_PTR(domain);
|
||||
if (ret_domain)
|
||||
*ret_domain = TAKE_PTR(domain);
|
||||
|
||||
if (_type)
|
||||
*_type = TAKE_PTR(type);
|
||||
if (ret_type)
|
||||
*ret_type = TAKE_PTR(type);
|
||||
|
||||
if (_name)
|
||||
*_name = TAKE_PTR(name);
|
||||
if (ret_name)
|
||||
*ret_name = TAKE_PTR(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ bool dnssd_srv_type_is_valid(const char *name);
|
||||
bool dns_service_name_is_valid(const char *name);
|
||||
|
||||
int dns_service_join(const char *name, const char *type, const char *domain, char **ret);
|
||||
int dns_service_split(const char *joined, char **name, char **type, char **domain);
|
||||
int dns_service_split(const char *joined, char **ret_name, char **ret_type, char **ret_domain);
|
||||
|
||||
int dns_name_suffix(const char *name, unsigned n_labels, const char **ret);
|
||||
int dns_name_count_labels(const char *name);
|
||||
|
@ -540,6 +540,7 @@ TEST(dns_service_split) {
|
||||
test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", ".", 0);
|
||||
test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
|
||||
test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
|
||||
test_dns_service_split_one("_Q._Q-------------------------------------------------------------", NULL, "_Q._Q-------------------------------------------------------------", ".", 0);
|
||||
}
|
||||
|
||||
static void test_dns_name_change_suffix_one(const char *name, const char *old_suffix, const char *new_suffix, int r, const char *result) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user