Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108648007
D47668.id146915.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D47668.id146915.diff
View Options
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3818,6 +3818,7 @@
kern/kern_idle.c standard
kern/kern_intr.c standard
kern/kern_jail.c standard
+kern/kern_jailmeta.c standard
kern/kern_kcov.c optional kcov \
compile-with "${NOSAN_C} ${MSAN_CFLAGS}"
kern/kern_khelp.c standard
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -4254,7 +4254,7 @@
/*
* Jail-related sysctls.
*/
-static SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"Jails");
#if defined(INET) || defined(INET6)
diff --git a/sys/kern/kern_jailmeta.c b/sys/kern/kern_jailmeta.c
new file mode 100644
--- /dev/null
+++ b/sys/kern/kern_jailmeta.c
@@ -0,0 +1,341 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 SkunkWerks GmbH
+ *
+ * This software was developed by Igor Ostapenko <igoro@FreeBSD.org>
+ * under sponsorship from SkunkWerks GmbH.
+ */
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/sx.h>
+#include <sys/kernel.h>
+#include <sys/mount.h>
+#include <sys/malloc.h>
+#include <sys/jail.h>
+#include <sys/osd.h>
+#include <sys/proc.h>
+
+/*
+ * Buffer limit
+ *
+ * The hard limit is the actual value used during setting or modification. The
+ * soft limit is used solely by the security.jail.param.metaext & .metaint
+ * sysctlS. The soft limit may remain higher than the hard limit to ensure that
+ * previously set long meta strings can still be correctly interpreted by
+ * end-user interfaces like jls(8).
+ */
+
+static uint32_t jm_maxbufsize_hard = 4096;
+static uint32_t jm_maxbufsize_soft = 4096;
+
+static int
+jm_sysctl_meta_maxbufsize(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ uint32_t newmax = 0;
+
+ if (req->newptr == NULL) {
+ /* read-only */
+ sx_slock(&allprison_lock);
+ error = SYSCTL_OUT(req, &jm_maxbufsize_hard,
+ sizeof(jm_maxbufsize_hard));
+ sx_sunlock(&allprison_lock);
+ } else {
+ /* read and write */
+ sx_xlock(&allprison_lock);
+ error = SYSCTL_IN(req, &newmax, sizeof(newmax));
+ if (error == 0 && newmax < 1)
+ error = EINVAL;
+ if (error == 0) {
+ jm_maxbufsize_hard = newmax;
+ if (jm_maxbufsize_hard >= jm_maxbufsize_soft)
+ jm_maxbufsize_soft = jm_maxbufsize_hard;
+ else if (TAILQ_EMPTY(&allprison))
+ /*
+ * TODO: For now, this is the simplest way to
+ * avoid O(n) iteration over all prisons in
+ * cases of a large n.
+ */
+ jm_maxbufsize_soft = jm_maxbufsize_hard;
+ }
+ sx_xunlock(&allprison_lock);
+ }
+
+ return (error);
+}
+SYSCTL_PROC(_security_jail, OID_AUTO, meta_maxbufsize,
+ CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
+ jm_sysctl_meta_maxbufsize, "IU", "Maximum meta buffer size.");
+
+
+/* Jail parameter announcement */
+
+static int
+jm_sysctl_param_meta(SYSCTL_HANDLER_ARGS)
+{
+ uint32_t soft;
+
+ sx_slock(&allprison_lock);
+ soft = jm_maxbufsize_soft;
+ sx_sunlock(&allprison_lock);
+
+ return (sysctl_jail_param(oidp, arg1, soft, req));
+}
+SYSCTL_PROC(_security_jail_param, OID_AUTO, metaext,
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
+ jm_sysctl_param_meta, "A", "Jail external meta information");
+SYSCTL_PROC(_security_jail_param, OID_AUTO, metaint,
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
+ jm_sysctl_param_meta, "A", "Jail internal meta information");
+
+
+/* OSD -- general */
+
+struct meta {
+ char *name;
+ u_int osd_slot;
+ osd_method_t methods[PR_MAXMETHOD];
+};
+
+static int
+jm_osd_method_set(void *obj, void *data, struct meta *meta)
+{
+ struct prison *pr = obj;
+ struct vfsoptlist *opts = data;
+ int len = 0;
+ char *osd_addr;
+ char *osd_addr_old;
+ int error;
+
+ /* Check the option presence and its len before buf allocation */
+ error = vfs_getopt(opts, meta->name, NULL, &len);
+ if (error == ENOENT)
+ return (0);
+ if (error != 0)
+ return (error);
+ if (len < 1)
+ return (EINVAL);
+
+ sx_assert(&allprison_lock, SA_LOCKED);
+ if (len > jm_maxbufsize_hard) /* len includes '\0' char */
+ return (EFBIG);
+
+ /* Prepare a new buf */
+ osd_addr = NULL;
+ if (len > 1) {
+ osd_addr = malloc(len, M_PRISON, M_WAITOK);
+ error = vfs_copyopt(opts, meta->name, osd_addr, len);
+ if (error != 0) {
+ free(osd_addr, M_PRISON);
+ return (error);
+ }
+ }
+
+ /* Swap bufs */
+ mtx_lock(&pr->pr_mtx);
+ osd_addr_old = osd_jail_get(pr, meta->osd_slot);
+ error = osd_jail_set(pr, meta->osd_slot, osd_addr);
+ mtx_unlock(&pr->pr_mtx);
+
+ if (error != 0)
+ osd_addr_old = osd_addr;
+
+ free(osd_addr_old, M_PRISON);
+
+ return (error);
+}
+
+static int
+jm_osd_method_get(void *obj, void *data, struct meta *meta)
+{
+ struct prison *pr = obj;
+ struct vfsoptlist *opts = data;
+ char *osd_addr = NULL;
+ char empty = '\0';
+ int error;
+
+ /* Check the option presence to avoid unnecessary locking */
+ error = vfs_getopt(opts, meta->name, NULL, NULL);
+ if (error == ENOENT)
+ return (0);
+ if (error != 0)
+ return (error);
+
+ mtx_lock(&pr->pr_mtx);
+ osd_addr = osd_jail_get(pr, meta->osd_slot);
+ if (osd_addr == NULL)
+ error = vfs_setopts(opts, meta->name, &empty);
+ else
+ error = vfs_setopts(opts, meta->name, osd_addr);
+ mtx_unlock(&pr->pr_mtx);
+
+ return (error);
+}
+
+static int
+jm_osd_method_check(void *obj __unused, void *data, struct meta *meta)
+{
+ struct vfsoptlist *opts = data;
+ char *value = NULL;
+ int error;
+ int len = 0;
+
+ /* Check the option presence */
+ error = vfs_getopt(opts, meta->name, (void **)&value, &len);
+ if (error == ENOENT)
+ return (0);
+ if (error != 0)
+ return (error);
+
+ if (len < 1)
+ return (EINVAL);
+ if (value == NULL)
+ return (EINVAL);
+
+ return (0);
+}
+
+static void
+jm_osd_destructor(void *osd_addr)
+{
+ free(osd_addr, M_PRISON);
+}
+
+
+/* OSD -- metaext */
+
+static struct meta metaext;
+
+static inline int
+jm_osd_method_set_metaext(void *obj, void *data)
+{
+ return (jm_osd_method_set(obj, data, &metaext));
+}
+
+static inline int
+jm_osd_method_get_metaext(void *obj, void *data)
+{
+ return (jm_osd_method_get(obj, data, &metaext));
+}
+
+static inline int
+jm_osd_method_check_metaext(void *obj __unused, void *data)
+{
+ return (jm_osd_method_check(obj, data, &metaext));
+}
+
+static struct meta metaext = {
+ .name = "metaext",
+ .osd_slot = 0,
+ .methods = {
+ [PR_METHOD_SET] = jm_osd_method_set_metaext,
+ [PR_METHOD_GET] = jm_osd_method_get_metaext,
+ [PR_METHOD_CHECK] = jm_osd_method_check_metaext,
+ }
+};
+
+
+/* OSD -- metaint */
+
+static struct meta metaint;
+
+static inline int
+jm_osd_method_set_metaint(void *obj, void *data)
+{
+ return (jm_osd_method_set(obj, data, &metaint));
+}
+
+static inline int
+jm_osd_method_get_metaint(void *obj, void *data)
+{
+ return (jm_osd_method_get(obj, data, &metaint));
+}
+
+static inline int
+jm_osd_method_check_metaint(void *obj __unused, void *data)
+{
+ return (jm_osd_method_check(obj, data, &metaint));
+}
+
+static struct meta metaint = {
+ .name = "metaint",
+ .osd_slot = 0,
+ .methods = {
+ [PR_METHOD_SET] = jm_osd_method_set_metaint,
+ [PR_METHOD_GET] = jm_osd_method_get_metaint,
+ [PR_METHOD_CHECK] = jm_osd_method_check_metaint,
+ }
+};
+
+
+/* A jail can read its internal meta */
+
+static int
+jm_sysctl_metaint(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ char empty = '\0';
+ char *tmpbuf;
+ size_t outlen;
+ int error = 0;
+
+ pr = req->td->td_ucred->cr_prison;
+
+ mtx_lock(&pr->pr_mtx);
+ arg1 = osd_jail_get(pr, metaint.osd_slot);
+ if (arg1 == NULL) {
+ tmpbuf = ∅
+ outlen = 1;
+ } else {
+ outlen = strlen(arg1) + 1;
+ if (req->oldptr != NULL) {
+ tmpbuf = malloc(outlen, M_PRISON, M_NOWAIT);
+ error = (tmpbuf == NULL) ? ENOMEM : 0;
+ if (error == 0)
+ memcpy(tmpbuf, arg1, outlen);
+ }
+ }
+ mtx_unlock(&pr->pr_mtx);
+
+ if (error != 0)
+ return (error);
+
+ if (req->oldptr == NULL)
+ SYSCTL_OUT(req, NULL, outlen);
+ else {
+ SYSCTL_OUT(req, tmpbuf, outlen);
+ if (tmpbuf != &empty)
+ free(tmpbuf, M_PRISON);
+ }
+
+ return (error);
+}
+SYSCTL_PROC(_security_jail, OID_AUTO, metaint,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ 0, 0, jm_sysctl_metaint, "A", "Jail internal meta information");
+
+
+/* Setup and tear down */
+
+static int
+jm_sysinit(void *arg __unused)
+{
+ metaext.osd_slot = osd_jail_register(jm_osd_destructor, metaext.methods);
+ metaint.osd_slot = osd_jail_register(jm_osd_destructor, metaint.methods);
+
+ return (0);
+}
+
+static int
+jm_sysuninit(void *arg __unused)
+{
+ osd_jail_deregister(metaext.osd_slot);
+ osd_jail_deregister(metaint.osd_slot);
+
+ return (0);
+}
+
+SYSINIT(jailmeta, SI_SUB_DRIVERS, SI_ORDER_ANY, jm_sysinit, NULL);
+SYSUNINIT(jailmeta, SI_SUB_DRIVERS, SI_ORDER_ANY, jm_sysuninit, NULL);
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -376,6 +376,7 @@
/*
* Sysctls to describe jail parameters.
*/
+SYSCTL_DECL(_security_jail);
SYSCTL_DECL(_security_jail_param);
#define SYSCTL_JAIL_PARAM(module, param, type, fmt, descr) \
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -57,6 +57,7 @@
TEST_METADATA.sigsys+= is_exclusive="true"
ATF_TESTS_SH+= coredump_phnum_test
+ATF_TESTS_SH+= jailmeta
ATF_TESTS_SH+= sonewconn_overflow
TEST_METADATA.sonewconn_overflow+= required_programs="python"
TEST_METADATA.sonewconn_overflow+= required_user="root"
diff --git a/tests/sys/kern/jailmeta.sh b/tests/sys/kern/jailmeta.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/kern/jailmeta.sh
@@ -0,0 +1,401 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 SkunkWerks GmbH
+#
+# This software was developed by Igor Ostapenko <igoro@FreeBSD.org>
+# under sponsorship from SkunkWerks GmbH.
+#
+
+setup()
+{
+ if [ $(sysctl -n security.jail.meta_maxbufsize) -lt 10 ]; then
+ atf_skip "sysctl security.jail.meta_maxbufsize must be 10+ for testing."
+ fi
+}
+
+atf_test_case "jail_create" "cleanup"
+jail_create_head()
+{
+ atf_set descr 'Test that meta can be set upon jail creation with jail(8)'
+ atf_set require.user root
+ atf_set execenv jail
+}
+jail_create_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="a b c" metaint="C B A"
+
+ atf_check -s exit:0 -o inline:"a b c\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"C B A\n" \
+ jls -j jail1 metaint
+}
+jail_create_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "jail_modify" "cleanup"
+jail_modify_head()
+{
+ atf_set descr 'Test that meta can be modified after jail creation with jail(8)'
+ atf_set require.user root
+ atf_set execenv jail
+}
+jail_modify_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="a b c" metaint="internal"
+
+ atf_check -s exit:0 -o inline:"a b c\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"internal\n" \
+ jls -j jail1 metaint
+
+ atf_check -s exit:0 \
+ jail -m name=jail1 metaext="t1=A t2=B" metaint="internal2"
+
+ atf_check -s exit:0 -o inline:"t1=A t2=B\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"internal2\n" \
+ jls -j jail1 metaint
+}
+jail_modify_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "jail_add" "cleanup"
+jail_add_head()
+{
+ atf_set descr 'Test that meta can be added to an existing jail with jail(8)'
+ atf_set require.user root
+ atf_set execenv jail
+}
+jail_add_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist host.hostname=jail1
+
+ atf_check -s exit:0 -o inline:'""\n' \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:'""\n' \
+ jls -j jail1 metaint
+
+ atf_check -s exit:0 \
+ jail -m name=jail1 metaext="$(jot 3 1 3)" metaint="$(jot 2 11 12)"
+
+ atf_check -s exit:0 -o inline:"1\n2\n3\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"11\n12\n" \
+ jls -j jail1 metaint
+}
+jail_add_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "jail_reset" "cleanup"
+jail_reset_head()
+{
+ atf_set descr 'Test that meta can be reset to an empty string with jail(8)'
+ atf_set require.user root
+ atf_set execenv jail
+}
+jail_reset_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="123" metaint="456"
+
+ atf_check -s exit:0 -o inline:"123\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"456\n" \
+ jls -j jail1 metaint
+
+ atf_check -s exit:0 \
+ jail -m name=jail1 metaext= metaint=
+
+ atf_check -s exit:0 -o inline:'""\n' \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:'""\n' \
+ jls -j jail1 metaint
+}
+jail_reset_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "jls_libxo" "cleanup"
+jls_libxo_head()
+{
+ atf_set descr 'Test that meta can be read with jls(8) using libxo'
+ atf_set require.user root
+ atf_set execenv jail
+}
+jls_libxo_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="a b c" metaint="1 2 3"
+
+ atf_check -s exit:0 -o inline:'{"__version": "2", "jail-information": {"jail": [{"name":"jail1","metaext":"a b c"}]}}\n' \
+ jls -j jail1 --libxo json name metaext
+ atf_check -s exit:0 -o inline:'{"__version": "2", "jail-information": {"jail": [{"metaint":"1 2 3"}]}}\n' \
+ jls -j jail1 --libxo json metaint
+}
+jls_libxo_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "flua_create" "cleanup"
+flua_create_head()
+{
+ atf_set descr 'Test that meta can be set upon jail creation with flua'
+ atf_set require.user root
+ atf_set execenv jail
+}
+flua_create_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ /usr/libexec/flua -ljail -e 'jail.setparams("jail1", {["metaext"]="t1 t2=v2", ["metaint"]="secret", ["persist"]="true"}, jail.CREATE)'
+
+ atf_check -s exit:0 -o inline:"t1 t2=v2\n" \
+ /usr/libexec/flua -ljail -e 'jid, res = jail.getparams("jail1", {"metaext"}); print(res["metaext"])'
+ atf_check -s exit:0 -o inline:"secret\n" \
+ /usr/libexec/flua -ljail -e 'jid, res = jail.getparams("jail1", {"metaint"}); print(res["metaint"])'
+}
+flua_create_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "flua_modify" "cleanup"
+flua_modify_head()
+{
+ atf_set descr 'Test that meta can be changed with flua after jail creation'
+ atf_set require.user root
+ atf_set execenv jail
+}
+flua_modify_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="ABC" metaint="123"
+
+ atf_check -s exit:0 -o inline:"ABC\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"123\n" \
+ jls -j jail1 metaint
+
+ atf_check -s exit:0 \
+ /usr/libexec/flua -ljail -e 'jail.setparams("jail1", {["metaext"]="t1 t2=v", ["metaint"]="4"}, jail.UPDATE)'
+
+ atf_check -s exit:0 -o inline:"t1 t2=v\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"4\n" \
+ jls -j jail1 metaint
+}
+flua_modify_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "readable_from_jail" "cleanup"
+readable_from_jail_head()
+{
+ atf_set descr 'Test that a jail can read its internal meta parameter via sysctl(8)'
+ atf_set require.user root
+ atf_set execenv jail
+}
+readable_from_jail_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j jail1
+
+ atf_check -s exit:0 \
+ jail -c name=jail1 persist metaext="a b c" metaint="internal data"
+
+ atf_check -s exit:0 -o inline:"a b c\n" \
+ jls -j jail1 metaext
+ atf_check -s exit:0 -o inline:"internal data\n" \
+ jls -j jail1 metaint
+
+ atf_check -s exit:0 -o inline:"internal data\n" \
+ jexec jail1 sysctl -n security.jail.metaint
+}
+readable_from_jail_cleanup()
+{
+ jail -r jail1
+ return 0
+}
+
+atf_test_case "not_inheritable" "cleanup"
+not_inheritable_head()
+{
+ atf_set descr 'Test that a jail does not inherit meta parameter from its parent jail'
+ atf_set require.user root
+ atf_set execenv jail
+}
+not_inheritable_body()
+{
+ setup
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j parent
+
+ atf_check -s exit:0 \
+ jail -c name=parent children.max=1 persist metaext="parent-ext" metaint="parent-int"
+
+ jexec parent jail -c name=child persist
+
+ atf_check -s exit:0 -o inline:"parent-ext\n" \
+ jls -j parent metaext
+ atf_check -s exit:0 -o inline:'""\n' \
+ jls -j parent.child metaext
+
+ atf_check -s exit:0 -o inline:"parent-int\n" \
+ jexec parent sysctl -n security.jail.metaint
+ atf_check -s exit:0 -o inline:"\n" \
+ jexec parent.child sysctl -n security.jail.metaint
+}
+not_inheritable_cleanup()
+{
+ jail -r parent.child
+ jail -r parent
+ return 0
+}
+
+atf_test_case "maxbufsize" "cleanup"
+maxbufsize_head()
+{
+ atf_set descr 'Test that meta buffer maximum size can be changed via sysctl from prison0'
+ atf_set require.user root
+}
+maxbufsize_body()
+{
+ setup
+
+ jn=jailmeta_maxbufsize
+
+ atf_check -s not-exit:0 -e match:"not found" -o ignore \
+ jls -j $jn
+
+ # the size counts string length and the trailing \0 char
+ origmax=$(sysctl -n security.jail.meta_maxbufsize)
+
+ # must be fine with current max
+ atf_check -s exit:0 \
+ jail -c name=$jn persist metaext="$(printf %$((origmax-1))s)"
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaext | wc -c
+ #
+ atf_check -s exit:0 \
+ jail -m name=$jn metaint="$(printf %$((origmax-1))s)"
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaint | wc -c
+
+ # should not allow exceeding current max
+ atf_check -s not-exit:0 -e match:"too large" \
+ jail -m name=$jn metaext="$(printf %${origmax}s)"
+ #
+ atf_check -s not-exit:0 -e match:"too large" \
+ jail -m name=$jn metaint="$(printf %${origmax}s)"
+
+ # should allow the same size with increased max
+ newmax=$((origmax + 1))
+ sysctl security.jail.meta_maxbufsize=$newmax
+ atf_check -s exit:0 \
+ jail -m name=$jn metaext="$(printf %${origmax}s)"
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaext | wc -c
+ #
+ atf_check -s exit:0 \
+ jail -m name=$jn metaint="$(printf %${origmax}s)"
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaint | wc -c
+
+ # decrease back to the original max
+ sysctl security.jail.meta_maxbufsize=$origmax
+ atf_check -s not-exit:0 -e match:"too large" \
+ jail -m name=$jn metaext="$(printf %${origmax}s)"
+ #
+ atf_check -s not-exit:0 -e match:"too large" \
+ jail -m name=$jn metaint="$(printf %${origmax}s)"
+
+ # the previously set long meta is still readable as is
+ # due to the soft limit remains higher than the hard limit
+ atf_check_equal "${newmax}" "$(sysctl -n security.jail.param.metaext)"
+ atf_check_equal "${newmax}" "$(sysctl -n security.jail.param.metaint)"
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaext | wc -c
+ #
+ atf_check -s exit:0 -o inline:"${origmax}\n" \
+ jls -j $jn metaint | wc -c
+}
+maxbufsize_cleanup()
+{
+ jail -r jailmeta_maxbufsize
+ return 0
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case "jail_create"
+ atf_add_test_case "jail_modify"
+ atf_add_test_case "jail_add"
+ atf_add_test_case "jail_reset"
+
+ atf_add_test_case "jls_libxo"
+
+ atf_add_test_case "flua_create"
+ atf_add_test_case "flua_modify"
+
+ atf_add_test_case "readable_from_jail"
+ atf_add_test_case "not_inheritable"
+
+ atf_add_test_case "maxbufsize"
+}
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -513,6 +513,21 @@
The number for the jail's
.Va kern.osreldate
and uname -K.
+.It Va metaext , Va metaint
+Any string associated with the jail.
+Its buffer size is limited by the global
+.Va security.jail.meta_maxbufsize
+sysctl, which can only be tuned by the non-jailed root user.
+The
+.Va metaext
+is an external meta information which can be read only by parent jail(s).
+The
+.Va metaint
+is an internal meta information which can be read by both,
+the jail and its parents.
+The jail can read it via
+.Va security.jail.metaint
+sysctl.
.It Va allow.*
Some restrictions of the jail environment may be set on a per-jail
basis.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 1:54 AM (10 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16236626
Default Alt Text
D47668.id146915.diff (20 KB)
Attached To
Mode
D47668: jail: Add meta and env parameters
Attached
Detach File
Event Timeline
Log In to Comment