git: b2a270da9fbf - main - libjail: fix fetching mac.label for multiple jails
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 09 Sep 2026 21:24:34 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=b2a270da9fbf0fb58fb7c1bf1006ae675e14a5e3
commit b2a270da9fbf0fb58fb7c1bf1006ae675e14a5e3
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2026-09-09 21:24:18 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-09-09 21:24:18 +0000
libjail: fix fetching mac.label for multiple jails
When doing a basic `jls -n`, jls(8) will jailparam_get() the mac.label
for every jail on the system using the same set of jailparams, and thus
the same jp_value. We only init the mac_t the first time, so the first
jail would populate it with `?` from /etc/mac.conf and the resulting
jail_get(2) would clobber it with the empty string, then a second jail
would try to pass the empty string to the kernel and fail because it
must have a non-zero length.
Fix it by invoking jps_get() every time. Drop some comments to note
that jps_get() will be invoked with zero || garbage from previous call,
and be sure that we don't leak our previous mac_t. There aren't any
other jps_get implementations at this time, so this shouldn't cause any
unexpected problems.
Reported by: ivy
Reviewed by: jamie
Differential Revision: https://reviews.freebsd.org/D57280
---
lib/libjail/jail.c | 31 +++++++++++++++++++++++++------
usr.sbin/jail/tests/jail_basic_test.sh | 5 ++++-
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c
index 95ba336b62ce..c180b8533e97 100644
--- a/lib/libjail/jail.c
+++ b/lib/libjail/jail.c
@@ -746,13 +746,23 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags)
jiov[i].iov_base = jp[j].jp_name;
jiov[i].iov_len = strlen(jp[j].jp_name) + 1;
i++;
- if (jp[j].jp_value == NULL &&
- !(jp[j].jp_flags & JP_RAWVALUE)) {
- jp[j].jp_value = malloc(jp[j].jp_valuelen);
+
+ /*
+ * We give structured types' jps_get() implementations
+ * a chance to initialize the value. We'll guarantee
+ * that the initial value is zeroed out, but they should
+ * assume on every call that the value may be populated
+ * by a subsequent jailparam_get().
+ */
+ if (!(jp[j].jp_flags & JP_RAWVALUE)) {
if (jp[j].jp_value == NULL) {
- strerror_r(errno, jail_errmsg,
- JAIL_ERRMSGLEN);
- return (-1);
+ jp[j].jp_value = calloc(1,
+ jp[j].jp_valuelen);
+ if (jp[j].jp_value == NULL) {
+ strerror_r(errno, jail_errmsg,
+ JAIL_ERRMSGLEN);
+ return (-1);
+ }
}
/*
@@ -1435,6 +1445,15 @@ jps_get_mac_label(struct jailparam *jp, struct iovec *jiov)
mac_t *pmac = jp->jp_value;
int error;
+ /*
+ * Our value is only allocated once and may be reused for many
+ * jailparam_get() calls; avoid leaking.
+ */
+ if (*pmac != NULL) {
+ mac_free(*pmac);
+ *pmac = NULL;
+ }
+
error = mac_prepare_type(pmac, "jail");
if (error != 0 && errno == ENOENT) {
/*
diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh
index cb50a94a45e8..c662e44f1a16 100755
--- a/usr.sbin/jail/tests/jail_basic_test.sh
+++ b/usr.sbin/jail/tests/jail_basic_test.sh
@@ -35,6 +35,9 @@ basic_body()
{
# Create the jail
atf_check -s exit:0 -o ignore jail -c name=basejail persist ip4.addr=192.0.1.1
+ # Create a second jail to test `jls -n` in the process for breakage when
+ # handling some of the non-trivial parameter types.
+ atf_check -s exit:0 -o ignore jail -c name=basejail2 persist ip4.addr=192.0.1.2
# Check output of jls
atf_check -s exit:0 -o ignore jls
atf_check -s exit:0 -o ignore jls -v
@@ -52,7 +55,7 @@ basic_body()
basic_cleanup()
{
- jail -r basejail
+ jail -r basejail basejail2
}
atf_test_case "list" "cleanup"