By default, when a process in jail calls getfsstat(), only return the

data for the file system on which the jail's root vnode is located.
Previous behavior (show data for all mountpoints) can be restored
by setting security.jail.getfsstatroot_only to 0.  Note: this also
has the effect of hiding other mounts inside a jail, such as /dev,
/tmp, and /proc, but errs on the side of leaking less information.
This commit is contained in:
Robert Watson 2004-02-14 18:31:11 +00:00
parent 281591449a
commit f08df373a3
4 changed files with 39 additions and 0 deletions

View File

@ -54,6 +54,11 @@ SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
&jail_sysvipc_allowed, 0,
"Processes in jail can use System V IPC primitives");
int jail_getfsstatroot_only = 1;
SYSCTL_INT(_security_jail, OID_AUTO, getfsstate_getfsstatroot_only, CTLFLAG_RW,
&jail_getfsstatroot_only, 0,
"Processes see only their root file system in getfsstat()");
/* allprison, lastprid, and prisoncount are protected by allprison_mtx. */
struct prisonlist allprison;
struct mtx allprison_mtx;
@ -418,6 +423,21 @@ getcredhostname(struct ucred *cred, char *buf, size_t size)
strlcpy(buf, hostname, size);
}
/*
* Return 1 if the passed credential can "see" the passed mountpoint
* when performing a getfsstat(); otherwise, 0.
*/
int
prison_check_mount(struct ucred *cred, struct mount *mp)
{
if (jail_getfsstatroot_only) {
if (cred->cr_prison->pr_root->v_mount != mp)
return (0);
}
return (1);
}
static int
sysctl_jail_list(SYSCTL_HANDLER_ARGS)
{

View File

@ -341,6 +341,10 @@ getfsstat(td, uap)
count = 0;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (!prison_check_mount(td->td_ucred, mp)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
#ifdef MAC
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);
@ -519,6 +523,10 @@ freebsd4_getfsstat(td, uap)
count = 0;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (!prison_check_mount(td->td_ucred, mp)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
#ifdef MAC
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);

View File

@ -341,6 +341,10 @@ getfsstat(td, uap)
count = 0;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (!prison_check_mount(td->td_ucred, mp)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
#ifdef MAC
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);
@ -519,6 +523,10 @@ freebsd4_getfsstat(td, uap)
count = 0;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (!prison_check_mount(td->td_ucred, mp)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
#ifdef MAC
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);

View File

@ -81,6 +81,7 @@ struct prison {
extern int jail_set_hostname_allowed;
extern int jail_socket_unixiproute_only;
extern int jail_sysvipc_allowed;
extern int jail_getfsstat_jailrootonly;
LIST_HEAD(prisonlist, prison);
extern struct prisonlist allprison;
@ -89,10 +90,12 @@ extern struct prisonlist allprison;
* Kernel support functions for jail().
*/
struct ucred;
struct mount;
struct sockaddr;
int jailed(struct ucred *cred);
void getcredhostname(struct ucred *cred, char *, size_t);
int prison_check(struct ucred *cred1, struct ucred *cred2);
int prison_check_mount(struct ucred *cred, struct mount *mp);
void prison_free(struct prison *pr);
u_int32_t prison_getip(struct ucred *cred);
void prison_hold(struct prison *pr);