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:
parent
281591449a
commit
f08df373a3
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user