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"