From nobody Thu Apr 23 03:49:56 2026 X-Original-To: dev-commits-src-all@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 4g1MYK1cV8z6bTkh for ; Thu, 23 Apr 2026 03:49:57 +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 4g1MYK07F8z44kg for ; Thu, 23 Apr 2026 03:49:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1776916197; 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=G9dVZCgd501SR6jgMp3j55JmFPcf0KapiJ7M3UBiNGY=; b=dN19CDGACbeOPwDz8zJklQmEML9dNajvitOc7zFyAszAnnDsYYBdga15OCRDcMefVBGrO0 a14wLCMB63nXKwbfn0F5BfAT9FE/z3iBKG4V5YZHPDuM8A2h/ZW3JU+e/8VguSirzy0N49 ekoNcaoUxj4k6E5KlZdL5oooJ2XbNKleLOCz/9a4+AoQKoUvFOs1VPzZlnafvPPA0BPrn+ gxQG1rvDfj7LvKd0SN+BAlazFl1OJM395vDn/oYHch0w1FcBvIn6EM8VwiM2b2l9QNovkE 0WXRhMLEHqmF9Kmc5yqszGj0iHrj5REEZpqzr8S8P2PttO8ZQVZE2SA1usOgcQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1776916197; a=rsa-sha256; cv=none; b=uuKKisq1LMe8kMTC7Ti33g4b55Jn6cQeROd6i/fFWsXxP38ubCdyeNX5MyNuTghfKinkF1 iStwHrziaSxu/wEAJO9V1bYcRGIxDjBaGGxjeCYUXmnghJ58T5ItNKpt9U4JtB+CEB0YyU huvu7eVgVJjf+SrxF/6U7gVQv1J2Z6TCJ8n3BgVW9ezp2Q9bGoiDlZP9we4kuyZF7SpkbJ 0HNL3vHA0OB8Clbu986ooxE6zcU2w0qUMwA4p9ZsfOBkMei5dKjZ/5WF3n12WdLkVnj4N5 nGsmMVtvHjxDBmrAdfN6znXZ+h0am8tA3rlQywAUuwwmW/mU9Zn28UC7z9+Lag== 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=1776916197; 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=G9dVZCgd501SR6jgMp3j55JmFPcf0KapiJ7M3UBiNGY=; b=YmXmdZSE5k3413A9YuX0vVXroOGkZZR7p2ZgIEnu2IVXnP4GyA1l35L2Os+MB0+J6U65wJ 4S8BucqEAwfdgKs+o53hjWdAPMTw9o62LgBaqiht9/8/QfncOFA3VuhujQWWfL3MgG2L5Z 61PpJTusrOx2yY0P0I+re2lz0T51vXibA9Mp/O9jhigila08L2VaG6npQqhQqx0mYhMK9g 49ZaHnzsebX/m0jNXgc4z5fVTLQh0ipyLhn8MujFh5RJtsj7VDw2hVEUUC3Gqf/Q60g96A ErNJjm4fOHa+EVj1877PiR3YGjAVn1pcObURLkbeSF7qBHFQpzpoUMsnQnxabA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g1MYJ5njvz10Pj for ; Thu, 23 Apr 2026 03:49:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3ac9c by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 23 Apr 2026 03:49:56 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: df670d26ad5b - stable/14 - jail: consistently populate the KP_JID and KP_NAME parameters List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: df670d26ad5bebce71f39fc3bdc3ef11ed0f1ea8 Auto-Submitted: auto-generated Date: Thu, 23 Apr 2026 03:49:56 +0000 Message-Id: <69e996e4.3ac9c.14b0bfb4@gitrepo.freebsd.org> The branch stable/14 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=df670d26ad5bebce71f39fc3bdc3ef11ed0f1ea8 commit df670d26ad5bebce71f39fc3bdc3ef11ed0f1ea8 Author: Kyle Evans AuthorDate: 2025-07-26 03:13:44 +0000 Commit: Kyle Evans CommitDate: 2026-04-23 03:22:59 +0000 jail: consistently populate the KP_JID and KP_NAME parameters The gaps here, specifically, were: - When we have to discover a running jail's jid from name, we should populate the missing jid param - When we populate jid/name from the config, if the name is a jid we wouldn't populate the name; now we do both. - When we create a jail, we should populate jid and name with whatever details we have now that we didn't both. As a consequence, we can cleanup a few things: - vnet.interface and zfs.dataset can just always use the jid - Trying to populate JNAME should always work now, where it would be a little crashy before if you create a jail that didn't have a name or jid on the command line - We can simplify the just-prior JID population now that we'll keep a stringified jid in our intparams. This primarily fixes the below, but the issues with vnet.interface and zfs.dataset were pre-existing. Fixes: d8f021add40c3 ("jail: add JID, JNAME and JPATH to env [...]") Reviewed by: jamie (cherry picked from commit 02944d8c4969ffe97fcf84cb2ccb672e828c1d04) --- usr.sbin/jail/command.c | 36 ++++++--- usr.sbin/jail/config.c | 13 +++- usr.sbin/jail/jail.c | 7 ++ usr.sbin/jail/tests/jail_basic_test.sh | 129 +++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+), 12 deletions(-) diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c index 20f28abc6706..26eaeca442a9 100644 --- a/usr.sbin/jail/command.c +++ b/usr.sbin/jail/command.c @@ -291,8 +291,8 @@ run_command(struct cfjail *j) const struct cfstring *comstring, *s; login_cap_t *lcap; const char **argv; - char *acs, *ajidstr, *cs, *comcs, *devpath; - const char *jidstr, *conslog, *path, *ruleset, *term, *username; + char *acs, *cs, *comcs, *devpath; + const char *conslog, *path, *ruleset, *term, *username; enum intparam comparam; size_t comlen; pid_t pid; @@ -333,6 +333,25 @@ run_command(struct cfjail *j) printf("%d\n", j->jid); if (verbose >= 0 && (j->name || verbose > 0)) jail_note(j, "created\n"); + + /* + * Populate our jid and name parameters if they were not + * provided. This simplifies later logic that wants to + * use the jid or name to be able to do so reliably. + */ + if (j->intparams[KP_JID] == NULL) { + char ljidstr[16]; + + (void)snprintf(ljidstr, sizeof(ljidstr), "%d", + j->jid); + add_param(j, NULL, KP_JID, ljidstr); + } + + /* This matches the kernel behavior. */ + if (j->intparams[KP_NAME] == NULL) + add_param(j, j->intparams[KP_JID], KP_NAME, + NULL); + dep_done(j, DF_LIGHT); } return 0; @@ -457,8 +476,7 @@ run_command(struct cfjail *j) argv[0] = _PATH_IFCONFIG; argv[1] = comstring->s; argv[2] = down ? "-vnet" : "vnet"; - jidstr = string_param(j->intparams[KP_JID]); - argv[3] = jidstr ? jidstr : string_param(j->intparams[KP_NAME]); + argv[3] = string_param(j->intparams[KP_JID]); argv[4] = NULL; break; @@ -772,14 +790,10 @@ run_command(struct cfjail *j) endpwent(); } if (!injail) { - if (asprintf(&ajidstr, "%d", j->jid) == -1) { - jail_warnx(j, "asprintf jid=%d: %s", j->jid, - strerror(errno)); - exit(1); - } - setenv("JID", ajidstr, 1); - free(ajidstr); + if (string_param(j->intparams[KP_JID])) + setenv("JID", string_param(j->intparams[KP_JID]), 1); setenv("JNAME", string_param(j->intparams[KP_NAME]), 1); + path = string_param(j->intparams[KP_PATH]); setenv("JPATH", path ? path : "", 1); } diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c index 8c9ff0a7bd09..42498f01efd0 100644 --- a/usr.sbin/jail/config.c +++ b/usr.sbin/jail/config.c @@ -156,11 +156,14 @@ load_config(const char *cfname) TAILQ_CONCAT(&opp, &j->params, tq); /* * The jail name implies its "name" or "jid" parameter, - * though they may also be explicitly set later on. + * though they may also be explicitly set later on. After we + * collect other parameters, we'll go back and ensure they're + * both set if we need to do so here. */ add_param(j, NULL, strtol(j->name, &ep, 10) && !*ep ? KP_JID : KP_NAME, j->name); + /* * Collect parameters for the jail, global parameters/variables, * and any matching wildcard jails. @@ -180,6 +183,14 @@ load_config(const char *cfname) TAILQ_FOREACH(p, &opp, tq) add_param(j, p, 0, NULL); + /* + * We only backfill if it's the name that wasn't set; if it was + * the jid, we can assume that will be populated later when the + * jail is created or found. + */ + if (j->intparams[KP_NAME] == NULL) + add_param(j, j->intparams[KP_JID], KP_NAME, NULL); + /* Resolve any variable substitutions. */ pgen = 0; TAILQ_FOREACH(p, &j->params, tq) { diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c index 9e443c9f3f1d..c99fb162786b 100644 --- a/usr.sbin/jail/jail.c +++ b/usr.sbin/jail/jail.c @@ -887,7 +887,14 @@ running_jid(struct cfjail *j, int dflag) j->jid = -1; return; } + j->jid = jail_get(jiov, 2, dflag ? JAIL_DYING : 0); + if (j->jid > 0 && j->intparams[KP_JID] == NULL) { + char jidstr[16]; + + (void)snprintf(jidstr, sizeof(jidstr), "%d", j->jid); + add_param(j, NULL, KP_JID, jidstr); + } } static void diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh index 51ccafb45f60..a6859b4dc7f2 100755 --- a/usr.sbin/jail/tests/jail_basic_test.sh +++ b/usr.sbin/jail/tests/jail_basic_test.sh @@ -137,10 +137,139 @@ commands_cleanup() fi } +atf_test_case "jid_name_set" "cleanup" +jid_name_set_head() +{ + atf_set descr 'Test that one can set both the jid and name in a config file' + atf_set require.user root +} + +find_unused_jid() +{ + : ${JAIL_MAX=999999} + + # We'll start at a higher jid number and roll through the space until + # we find one that isn't taken. We start high to avoid racing parallel + # activity for the 'next available', though ideally we don't have a lot + # of parallel jail activity like that. + jid=5309 + while jls -cj "$jid"; do + if [ "$jid" -eq "$JAIL_MAX" ]; then + atf_skip "System has too many jail, cannot find free slot" + fi + + jid=$((jid + 1)) + done + + echo "$jid" | tee -a jails.lst +} +clean_jails() +{ + if [ ! -s jails.lst ]; then + return 0 + fi + + while read jail; do + if jls -e -j "$jail"; then + jail -r "$jail" + fi + done < jails.lst +} + +jid_name_set_body() +{ + local jid=$(find_unused_jid) + + echo "basejail" >> jails.lst + echo "$jid { name = basejail; persist; }" > jail.conf + atf_check -o match:"$jid: created" jail -f jail.conf -c "$jid" + atf_check -o match:"$jid: removed" jail -f jail.conf -r "$jid" + + echo "basejail { jid = $jid; persist; }" > jail.conf + atf_check -o match:"basejail: created" jail -f jail.conf -c basejail + atf_check -o match:"basejail: removed" jail -f jail.conf -r basejail +} + +jid_name_set_cleanup() +{ + clean_jails +} + +atf_test_case "param_consistency" "cleanup" +param_consistency_head() +{ + atf_set descr 'Test for consistency in jid/name params being set implicitly' + atf_set require.user root +} + +param_consistency_body() +{ + local iface jid + + echo "basejail" >> jails.lst + + # Most basic test: exec.poststart running a command without a jail + # config. This would previously crash as we only had the jid and name + # as populated at creation time. + atf_check jail -c path=/ exec.poststart="true" command=/usr/bin/true + + iface=$(ifconfig lo create) + atf_check test -n "$iface" + echo "$iface" >> interfaces.lst + + # Now do it again but exercising IP_VNET_INTERFACE, which is an + # implied command that wants to use the jid or name. This would crash + # as neither KP_JID or KP_NAME are populated when a jail is created, + # just as above- just at a different spot. + atf_check jail -c \ + path=/ vnet=new vnet.interface="$iface" command=/usr/bin/true + + # Test that a jail that we only know by name will have its jid resolved + # and added to its param set. + echo "basejail {path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf + + atf_check -o ignore jail -f jail.conf -c basejail + atf_check -o match:"STOP" jail -f jail.conf -r basejail + + # Do the same sequence as above, but use a jail with a jid-ish name. + jid=$(find_unused_jid) + echo "$jid {path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf + + atf_check -o ignore jail -f jail.conf -c "$jid" + atf_check -o match:"STOP" jail -f jail.conf -r "$jid" + + # Ditto, but now we set a name for that jid-jail. + echo "$jid {name = basejail; path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf + + atf_check -o ignore jail -f jail.conf -c "$jid" + atf_check -o match:"STOP" jail -f jail.conf -r "$jid" + + # Confirm that we have a valid jid available in exec.poststop. It's + # probably debatable whether we should or not. + echo "basejail {path = /; exec.poststop = 'echo JID=\$JID'; persist; }" > jail.conf + atf_check -o ignore jail -f jail.conf -c basejail + jid=$(jls -j basejail jid) + + atf_check -o match:"JID=$jid" jail -f jail.conf -r basejail + +} + +param_consistency_cleanup() +{ + clean_jails + + if [ -f "interfaces.lst" ]; then + while read iface; do + ifconfig "$iface" destroy + done < interfaces.lst + fi +} atf_init_test_cases() { atf_add_test_case "basic" atf_add_test_case "nested" atf_add_test_case "commands" + atf_add_test_case "jid_name_set" + atf_add_test_case "param_consistency" }