From nobody Sun Jun 28 18:40:22 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gpJBH1TgZz6jkYd for ; Sun, 28 Jun 2026 18:40:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gpJBG6nWPz3Y1v for ; Sun, 28 Jun 2026 18:40:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782672022; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vpDB5iMaPidi6iFUkS4cojUR9F/hxGV6DRT7Mbqu4Z0=; b=QwGTjcGCr8gvRdgsMUKjAMhjaJvf8JPs8nx3fsVWOt+ct6zrnGWrIY8+AUMUv/pyuXH0li 2tEGrraHZ563hCm9mRr96fhMHtTzY5MqCJFoWusayscFyKmzfRuzYF2EOE/bjD0cWJD6+B TCHmCpd+bR8JByYmBjpIpX52Mrx28lYYp7KxVvmElXUtH93mOxUEjD34wo+oXO4V8pfReW 7UKB/mB/JWjhUyY5xx27baFhA1VW9xrOrDi5YUtdEsYS1+Ux/T1WP5+k4u19/QDT2QO26r cMwKHVTG0cLlSj2R8KeLhg//Jqt2z7e2aLU0gU9SCxqa3EpjoB2bjIg80yQEbg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782672023; a=rsa-sha256; cv=none; b=Hx7HKy9o8OmoRImwhQeC0sU8Yi2p6BOXklYBF8aIFTTqoli32JkRH2qp0n8e9lA89dBRpX qaeMpYxqk9/f+zCn3uDvdRl9KNYLNSWsoqOXrWRTgDXUfAgVqpE78Z52CreJPcRfAmTIqs ViIf+HuaIliDn9dpWIw3KFCT6JtI3TD9gAkcD9feU67g2Tw3e5iT2hpTML/us82QSLcnqH GHkoOvfqn+Zf+4n0oKSss76jIbjY9hiUGv+rJZaQla/PuZ+QgUgCD0A5fpx+9edCHv36YH iYJseMm9kpAH98uq2IlIr8Mw06wq4cJnoOQzhoAmDR30A2BKO4A+BM3IhVmJ4A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782672023; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vpDB5iMaPidi6iFUkS4cojUR9F/hxGV6DRT7Mbqu4Z0=; b=I8NyJ6nVxCjPYex67q2MKBeTwcsL9H+XdoZR3IYwLn8ttFHaSuSEjVItcUIiYg+M/qp0B9 IIQB7b7FbHuHWslUYoX6Z4xld+6w/RSGvGk/IJYPe9elW9gCTlqwgZswNW8fy4NzX7nVwR Lk+jRSAqz8DyUCKJDXwjw/dqHGrZtPwg+j5nVIJiGt6i0eeC6Fkcp0s+I+X4pbzpUXO8Bt reCnycFqdBUgsVZW3HsXmyA/fFePZc8/htmQC+wBMhbAk+I8MpaJDdXiDmnUZ1fNya6cby E8Fe0/vEJXp/ML20ECQGRaWjaTNeFNJ2ObFk0fYyXm1IZ/TxwC+2fDt1emTPyA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gpJBG5rkDz6nb for ; Sun, 28 Jun 2026 18:40:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1cb4b by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 28 Jun 2026 18:40:22 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Baptiste Daroussin Subject: git: 2ebdc0a782a6 - stable/15 - nuageinit: add hostname validation (RFC 952/1123) to sethostname() List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bapt X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 2ebdc0a782a6c4ca7d6ab0ad8ead61d580921df1 Auto-Submitted: auto-generated Date: Sun, 28 Jun 2026 18:40:22 +0000 Message-Id: <6a416a96.1cb4b.2024d3fc@gitrepo.freebsd.org> The branch stable/15 has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=2ebdc0a782a6c4ca7d6ab0ad8ead61d580921df1 commit 2ebdc0a782a6c4ca7d6ab0ad8ead61d580921df1 Author: Baptiste Daroussin AuthorDate: 2026-06-04 18:26:49 +0000 Commit: Baptiste Daroussin CommitDate: 2026-06-28 18:32:24 +0000 nuageinit: add hostname validation (RFC 952/1123) to sethostname() Validate hostnames before writing them: - Reject empty hostnames - Reject hostnames longer than 253 characters - Reject hostnames with invalid characters - Reject hostnames starting or ending with dot/hyphen - Reject labels longer than 63 characters - Reject labels starting or ending with hyphen Expand the sethostname test to cover all rejection cases. Update nuage.sh sethostname_body to ignore stderr (warnings). (cherry picked from commit 46d1758aa7a2af37a356a93812b492a406c6ffd4) --- libexec/nuageinit/nuage.lua | 27 +++++++++++++ libexec/nuageinit/tests/nuage.sh | 2 +- libexec/nuageinit/tests/sethostname.lua | 68 +++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua index 4f25e79ccefc..a491ca8d9df6 100644 --- a/libexec/nuageinit/nuage.lua +++ b/libexec/nuageinit/nuage.lua @@ -119,6 +119,33 @@ local function sethostname(hostname) if hostname == nil then return end + -- Basic hostname validation (RFC 952/1123) + if #hostname == 0 then + warnmsg("hostname is empty, ignoring") + return + end + if #hostname > 253 then + warnmsg("hostname too long (" .. #hostname .. " > 253), ignoring") + return + end + if hostname:match("[^a-zA-Z0-9%.%-]") then + warnmsg("hostname contains invalid characters: " .. hostname) + return + end + if hostname:match("^[%.%-]") or hostname:match("[%.%-]$") then + warnmsg("hostname must not start or end with a dot or hyphen: " .. hostname) + return + end + for label in hostname:gmatch("[^.]+") do + if #label > 63 then + warnmsg("hostname label too long (" .. #label .. " > 63): " .. label) + return + end + if label:match("^-") or label:match("-$") then + warnmsg("hostname label starts or ends with hyphen: " .. label) + return + end + end local root = os.getenv("NUAGE_FAKE_ROOTDIR") if not root then root = "" diff --git a/libexec/nuageinit/tests/nuage.sh b/libexec/nuageinit/tests/nuage.sh index 348a8d93ba09..97c5224c7813 100644 --- a/libexec/nuageinit/tests/nuage.sh +++ b/libexec/nuageinit/tests/nuage.sh @@ -29,7 +29,7 @@ settimezone_body() sethostname_body() { - atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua + atf_check -e ignore /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua if [ ! -f etc/rc.conf.d/hostname ]; then atf_fail "hostname not written" fi diff --git a/libexec/nuageinit/tests/sethostname.lua b/libexec/nuageinit/tests/sethostname.lua index 47632497b545..0bc7eb2c4475 100644 --- a/libexec/nuageinit/tests/sethostname.lua +++ b/libexec/nuageinit/tests/sethostname.lua @@ -1,5 +1,73 @@ #!/usr/libexec/flua +--- +-- SPDX-License-Identifier: BSD-2-Clause +-- +-- Copyright (c) 2026 Baptiste Daroussin local n = require("nuage") +local root = os.getenv("NUAGE_FAKE_ROOTDIR") +if not root then + root = "" +end + +local hostnamepath = root .. "/etc/rc.conf.d/hostname" + +local function check_hostname(expected) + local f = io.open(hostnamepath, "r") + if not f then + n.err("hostname file not found, expected: " .. expected) + end + local content = f:read("*a") + f:close() + local expected_content = 'hostname="' .. expected:gsub('"', '\\"') .. '"\n' + if content ~= expected_content then + n.err("hostname mismatch: got '" .. content .. + "', expected '" .. expected_content .. "'") + end +end + +local function check_no_hostname() + if io.open(hostnamepath, "r") then + n.err("hostname file should not exist") + end +end + +-- nil hostname: no-op +n.sethostname(nil) +check_no_hostname() + +-- Empty hostname: invalid +n.sethostname("") +check_no_hostname() + +-- Hostname too long (>253 chars): invalid +n.sethostname(string.rep("a", 254)) +check_no_hostname() + +-- Invalid characters: invalid +n.sethostname("host;name") +check_no_hostname() + +-- Starts with dot: invalid +n.sethostname(".hostname") +check_no_hostname() + +-- Ends with hyphen: invalid +n.sethostname("hostname-") +check_no_hostname() + +-- Label too long (>63 chars): invalid +n.sethostname(string.rep("a", 64) .. ".example.com") +check_no_hostname() + +-- Label starts with hyphen: invalid +n.sethostname("myhost.-label.com") +check_no_hostname() + +-- Valid simple hostname +n.sethostname("myhostname") +check_hostname("myhostname") + +-- Final: set a valid hostname for the shell test n.sethostname("myhostname")