mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
jail: return a new descriptor from jail_get(JAIL_USE_DESC | JAIL_GET_DESC)
Prior to this change, `jail_get` when called with `JAIL_USE|JAIL_GET_DESC` would fail to return a valid descriptor in the positive case because the `JAIL_USE_DESC` block jumped to `found_prison` before the descriptor was allocated. This resulted in the returned jail descriptor always being -1, despite the call being successful. This change fixes the logic so `jfd_out` is properly initialized in the aforementioned scenario. MFC after: 3 days Reviewed by: jamie, ngie, adrian Differential Revision: https://reviews.freebsd.org/D60984
This commit is contained in:
1 parent
6c177745c5
commit
b3b50cbd46
2 files changed
+51
-7
No files matched your search
+11
-7
@@ -2645,6 +2645,17 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
|
||||
vfs_opterror(opts, "unexpected desc");
|
||||
goto done;
|
||||
}
|
||||
if (flags & (JAIL_GET_DESC | JAIL_OWN_DESC)) {
|
||||
/*
|
||||
* Allocate a jail descriptor to return later.
|
||||
* This must happen before the JAIL_USE_DESC
|
||||
* lookup below, which jumps to found_prison.
|
||||
*/
|
||||
error = jaildesc_alloc(td, &jfp_out, &jfd_out,
|
||||
flags & JAIL_OWN_DESC);
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
if (flags & JAIL_USE_DESC) {
|
||||
/* Get the jail from its descriptor. */
|
||||
error = jaildesc_find(td, jfd_in, &pr, NULL);
|
||||
@@ -2673,13 +2684,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
|
||||
prison_free(mypr);
|
||||
mypr = jdpr;
|
||||
}
|
||||
if (flags & (JAIL_GET_DESC | JAIL_OWN_DESC)) {
|
||||
/* Allocate a jail descriptor to return later. */
|
||||
error = jaildesc_alloc(td, &jfp_out, &jfd_out,
|
||||
flags & JAIL_OWN_DESC);
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
} else
|
||||
goto done;
|
||||
|
||||
|
||||
@@ -389,6 +389,45 @@ ATF_TC_BODY(at_desc_bad_fd, tc)
|
||||
ATF_REQUIRE_MSG(close(jd) == 0, "close: %s", strerror(errno));
|
||||
}
|
||||
|
||||
/*
|
||||
* Look a jail up by descriptor and ask for a descriptor back.
|
||||
*/
|
||||
ATF_TC(use_desc_get_desc);
|
||||
ATF_TC_HEAD(use_desc_get_desc, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "require.user", "root");
|
||||
}
|
||||
ATF_TC_BODY(use_desc_get_desc, tc)
|
||||
{
|
||||
struct iovec iov[2];
|
||||
int desc, jd, jid, n;
|
||||
|
||||
jd = create_jail("jaildesc_use_desc_get_desc");
|
||||
|
||||
desc = jd;
|
||||
n = 0;
|
||||
iov[n].iov_base = __DECONST(void *, "desc");
|
||||
iov[n++].iov_len = strlen("desc") + 1;
|
||||
iov[n].iov_base = &desc;
|
||||
iov[n++].iov_len = sizeof(desc);
|
||||
jid = jail_get(iov, n, JAIL_USE_DESC | JAIL_GET_DESC);
|
||||
ATF_REQUIRE_MSG(jid >= 0, "jail_get: %s", strerror(errno));
|
||||
ATF_REQUIRE_MSG(desc >= 0 && desc != jd,
|
||||
"jail_get returned descriptor %d, input was %d", desc, jd);
|
||||
|
||||
/* The returned descriptor must name the same jail. */
|
||||
n = 0;
|
||||
iov[n].iov_base = __DECONST(void *, "desc");
|
||||
iov[n++].iov_len = strlen("desc") + 1;
|
||||
iov[n].iov_base = &desc;
|
||||
iov[n++].iov_len = sizeof(desc);
|
||||
ATF_REQUIRE_MSG(jail_get(iov, n, JAIL_USE_DESC) == jid,
|
||||
"jail_get: %s", strerror(errno));
|
||||
|
||||
ATF_REQUIRE_MSG(close(desc) == 0, "close: %s", strerror(errno));
|
||||
ATF_REQUIRE_MSG(close(jd) == 0, "close: %s", strerror(errno));
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, poll_close_race);
|
||||
@@ -397,6 +436,7 @@ ATF_TP_ADD_TCS(tp)
|
||||
ATF_TP_ADD_TC(tp, curjail_get);
|
||||
ATF_TP_ADD_TC(tp, self_destruct);
|
||||
ATF_TP_ADD_TC(tp, at_desc_bad_fd);
|
||||
ATF_TP_ADD_TC(tp, use_desc_get_desc);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
Reference in new issue
Block a user