From 6528693a94821e0e13a8e112fb481c4ab0c62688 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Aug 2018 16:28:23 +0900 Subject: [PATCH 1/5] network: also check that Hostname= is a valid DNS domain name --- src/network/networkd-network.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 1f1cdced8f..eb13e9e93d 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -971,7 +971,8 @@ int config_parse_hostname( void *data, void *userdata) { - char **hostname = data, *hn = NULL; + _cleanup_free_ char *hn = NULL; + char **hostname = data; int r; assert(filename); @@ -984,13 +985,20 @@ int config_parse_hostname( if (!hostname_is_valid(hn, false)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Hostname is not valid, ignoring assignment: %s", rvalue); - free(hn); return 0; } - free(*hostname); - *hostname = hostname_cleanup(hn); - return 0; + r = dns_name_is_valid(hn); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue); + return 0; + } + if (r == 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue); + return 0; + } + + return free_and_replace(*hostname, hn); } int config_parse_timezone( From 19f9e4e2c8e413927e84b0cd528235a4af836878 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Aug 2018 16:28:44 +0900 Subject: [PATCH 2/5] network: use free_and_replace() --- src/network/networkd-network.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index eb13e9e93d..c8f7c4f98a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1013,7 +1013,8 @@ int config_parse_timezone( void *data, void *userdata) { - char **datap = data, *tz = NULL; + _cleanup_free_ char *tz = NULL; + char **datap = data; int r; assert(filename); @@ -1026,14 +1027,10 @@ int config_parse_timezone( if (!timezone_is_valid(tz, LOG_ERR)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Timezone is not valid, ignoring assignment: %s", rvalue); - free(tz); return 0; } - free(*datap); - *datap = tz; - - return 0; + return free_and_replace(*datap, tz); } int config_parse_dhcp_server_dns( From a8494759b4f14af5337391727ba295ab708b92f9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Aug 2018 16:31:10 +0900 Subject: [PATCH 3/5] network: DHCP: ignore error in setting hostname when it is given by uname() C.f. #9759. --- src/network/networkd-dhcp4.c | 11 +++++++++-- src/network/networkd-dhcp6.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 5616046f4f..08656334e0 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -599,7 +599,14 @@ static int dhcp4_set_hostname(Link *link) { hn = hostname; } - return sd_dhcp_client_set_hostname(link->dhcp_client, hn); + r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); + if (r == -EINVAL && hostname) + /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */ + log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); + else if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); + + return 0; } static bool promote_secondaries_enabled(const char *ifname) { @@ -737,7 +744,7 @@ int dhcp4_configure(Link *link) { r = dhcp4_set_hostname(link); if (r < 0) - return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); + return r; if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index e954754c20..0ec4deb716 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -453,7 +453,14 @@ static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) { hn = hostname; } - return sd_dhcp6_client_set_fqdn(client, hn); + r = sd_dhcp6_client_set_fqdn(client, hn); + if (r == -EINVAL && hostname) + /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */ + log_link_warning_errno(link, r, "DHCP6 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); + else if (r < 0) + return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set hostname: %m"); + + return 0; } int dhcp6_configure(Link *link) { @@ -497,7 +504,7 @@ int dhcp6_configure(Link *link) { r = dhcp6_set_hostname(client, link); if (r < 0) - return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set hostname: %m"); + return r; r = sd_dhcp6_client_set_ifindex(client, link->ifindex); if (r < 0) From 31ee39732705b74c43b2352132e3af205a876c99 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Aug 2018 16:32:42 +0900 Subject: [PATCH 4/5] man: mention that Hostname= for DHCP must be a valid DNS domain name --- man/systemd.network.xml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 8a80b0cf4f..c3dd8d07a9 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1194,25 +1194,28 @@ SendHostname= - When true (the default), the machine's hostname will - be sent to the DHCP server. + When true (the default), the machine's hostname will be sent to the DHCP server. + Note that the machine's hostname must consist only of 7-bit ASCII lower-case characters and + no spaces or dots, and be formatted as a valid DNS domain name. Otherwise, the hostname is not + send even if this is set to true. UseHostname= When true (the default), the hostname received from - the DHCP server will be set as the transient hostname of the system + the DHCP server will be set as the transient hostname of the system. - Hostname= - - Use this value for the hostname which is sent to the - DHCP server, instead of machine's hostname. - - + Hostname= + + Use this value for the hostname which is sent to the DHCP server, instead of machine's hostname. + Note that the specified hostname must consist only of 7-bit ASCII lower-case characters and + no spaces or dots, and be formatted as a valid DNS domain name. + + UseDomains= From 10c6e7e51ec515a509698120ea13cb2e0a325a3a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Aug 2018 16:54:27 +0900 Subject: [PATCH 5/5] resolve: fix error handling of dns_name_is_valid() --- src/resolve/resolved-dns-trust-anchor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/resolve/resolved-dns-trust-anchor.c b/src/resolve/resolved-dns-trust-anchor.c index 533e438fae..bf5b07cdd3 100644 --- a/src/resolve/resolved-dns-trust-anchor.c +++ b/src/resolve/resolved-dns-trust-anchor.c @@ -218,7 +218,10 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u if (r < 0) return log_warning_errno(r, "Unable to parse domain in line %s:%u: %m", path, line); - if (!dns_name_is_valid(domain)) { + r = dns_name_is_valid(domain); + if (r < 0) + return log_warning_errno(r, "Failed to chack validity of domain name '%s', at line %s:%u, ignoring line: %m", domain, path, line); + if (r == 0) { log_warning("Domain name %s is invalid, at line %s:%u, ignoring line.", domain, path, line); return -EINVAL; } @@ -385,7 +388,10 @@ static int dns_trust_anchor_load_negative(DnsTrustAnchor *d, const char *path, u if (r < 0) return log_warning_errno(r, "Unable to parse line %s:%u: %m", path, line); - if (!dns_name_is_valid(domain)) { + r = dns_name_is_valid(domain); + if (r < 0) + return log_warning_errno(r, "Failed to chack validity of domain name '%s', at line %s:%u, ignoring line: %m", domain, path, line); + if (r == 0) { log_warning("Domain name %s is invalid, at line %s:%u, ignoring line.", domain, path, line); return -EINVAL; }