[PATCH 3/4] common: hostname: validate the provided hostname

Marco Felsch m.felsch at pengutronix.de
Wed Mar 13 12:45:46 PDT 2024


Port the systemd hostname_is_valid() function to perform hostname
validation and inform the user about a invalid hostname.

Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
---
 common/misc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/common/misc.c b/common/misc.c
index e266f0951ee9..dc498ad0b318 100644
--- a/common/misc.c
+++ b/common/misc.c
@@ -13,6 +13,7 @@
 #include <led.h>
 #include <of.h>
 #include <restart.h>
+#include <string.h>
 #include <linux/stringify.h>
 
 int errno;
@@ -146,6 +147,67 @@ static char *hostname;
 static char *serial_number;
 static char *of_machine_compatible;
 
+/* Note that HOST_NAME_MAX is 64 on Linux */
+#define BAREBOX_HOST_NAME_MAX	64
+
+static bool barebox_valid_ldh_char(char c)
+{
+	/* "LDH" -> "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */
+	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+	       (c >= '0' && c <= '9') || c == '-';
+}
+
+static bool barebox_hostname_is_valid(const char *s)
+{
+	unsigned int n_dots = 0;
+	const char *p;
+	bool dot, hyphen;
+
+	/*
+	 * Check if s looks like a valid hostname or FQDN. This does not do full
+	 * DNS validation, but only checks if the name is composed of allowed
+	 * characters and the length is not above the maximum allowed by Linux.
+	 * Doesn't accept empty hostnames, hostnames with leading dots, and
+	 * hostnames with multiple dots in a sequence. Doesn't allow hyphens at
+	 * the beginning or end of label.
+	 */
+	if (isempty(s))
+		return false;
+
+	for (p = s, dot = hyphen = true; *p; p++) {
+		if (*p == '.') {
+			if (dot || hyphen)
+				return false;
+
+			dot = true;
+			hyphen = false;
+			n_dots++;
+
+		} else if (*p == '-') {
+			if (dot)
+				return false;
+
+			dot = false;
+			hyphen = true;
+
+		} else {
+			if (!barebox_valid_ldh_char(*p))
+				return false;
+
+			dot = false;
+			hyphen = false;
+		}
+	}
+
+	if (dot || hyphen)
+		return false;
+
+	if (p - s > BAREBOX_HOST_NAME_MAX)
+		return false;
+
+	return true;
+}
+
 /*
  * The hostname is supposed to be the shortname of a board. It should
  * contain only lowercase letters, numbers, '-', '_'. No whitespaces
@@ -156,6 +218,10 @@ void barebox_set_hostname(const char *__hostname)
 	globalvar_add_simple_string("hostname", &hostname);
 
 	free(hostname);
+
+	if (!barebox_hostname_is_valid(__hostname))
+		pr_warn("Hostname is not valid, please fix it\n");
+
 	hostname = xstrdup(__hostname);
 }
 
-- 
2.39.2




More information about the barebox mailing list