From nobody Thu Jun 4 21:15:43 2026 X-Original-To: dev-commits-src-main@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 4gWcmc01gfz6gxwB for ; Thu, 04 Jun 2026 21:15:44 +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 "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gWcmb1yq5z3LYd for ; Thu, 04 Jun 2026 21:15:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1780607743; 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=JwXz7j/gS+j8GfjknuU5verbgBDBhd5KuiH0ukO4ZZY=; b=oyxHd7VM0Qty9ELrJX83LPVNRqsf90R6Qg6otWdCN6UdCc8JCCfXX25ug8PMtZmBZCxNr4 WCMKT90rqOZhJbaUp7dCtgGJiSPl8Jc+P3BQDm/C5xeTQGNTw3Raqt+XqRye8AQ8r/W0l2 LVLrAiNeFo97YfQkGLIB7K1jJByyi0lEgCy8TiNqXTNvNcmtRYN+7PaUbx1eYl95E0qJBv ZTvAF1BHkJlkrYf8cvf8kImiKbVnVoOzRO5lR0gw8LYrdTkGalBTqvbe8by5L5qh29JUNk ATmepRGoMtc3+9d7/BRNX13Od0MFGULHLzfUNxsveQsoC3tzhaeb4MzGx6ihlw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1780607743; a=rsa-sha256; cv=none; b=nUdOXbJskiQ7MQnqbJ4ebTIvhQIIuOXm5mfuyzkeZAYPT/5es+ZS+3H6SJUocvxLhh5iVQ fM00Ak8U2g6kcKJ6kPoL+0EWpledNL+wflfgi56ET3m0J4bkFm0GIs8FPh71BtmeokvUfH blpF3JuMobUrJocH6wUaktghslL4KQD1cksgzBl8bDGBkRHGXycFwjmpqCSrZ6SINiLSml 0NA6iL8D5SCPni2P5QcLDzePhMF1ZmB6HvOzQj+EuzO9Bq7QQUu5U8VqcSKjsN5fA5qhoo 7/UrHMnUrhdTYcgy2CG2d8EESWUgXRLpoUAaeWC6AJkBDPbFvz2YQ30sXyxK1w== 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=1780607743; 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=JwXz7j/gS+j8GfjknuU5verbgBDBhd5KuiH0ukO4ZZY=; b=EQpC3Ei5+g5nnA+aw+PPpiZ6ZHAzrlVn7BZ+Zyz6S5/xEVauD7ZdqyOiCfgnhbx/lfVNXY SPp8byV4yDPVh/5f79mAksbGMZ1upamZr1v6NJ998ADrEchJBnc0HsTh5NgPnl8boS4nkV jigQ7YQiHVdw/+3gPhxb3rlC0pSZS3D+fFloxlA8KVBd6LYSmnrFOkyzIsAMWYDj9wKJt9 mA5EOvWzdwj1Fr4l7E3HavXfu+sw03ocacBbtUD8yQxPcMq4nTUQHDATv9UBDbzb/4Rczq wZj0k0Q64R3wVjIZPXrYrl6T4URzfZUt1y0rLp7PflD0iZTT5SuPAkYb6GqMpg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gWcmb1W9fz1DVk for ; Thu, 04 Jun 2026 21:15:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3c64e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 04 Jun 2026 21:15:43 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Baptiste Daroussin Subject: git: 46d1758aa7a2 - main - nuageinit: add hostname validation (RFC 952/1123) to sethostname() List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 46d1758aa7a2af37a356a93812b492a406c6ffd4 Auto-Submitted: auto-generated Date: Thu, 04 Jun 2026 21:15:43 +0000 Message-Id: <6a21eaff.3c64e.93541b5@gitrepo.freebsd.org> The branch main has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=46d1758aa7a2af37a356a93812b492a406c6ffd4 commit 46d1758aa7a2af37a356a93812b492a406c6ffd4 Author: Baptiste Daroussin AuthorDate: 2026-06-04 18:26:49 +0000 Commit: Baptiste Daroussin CommitDate: 2026-06-04 18:26:49 +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). --- 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")