summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_jail.c20
-rw-r--r--sys/kern/vfs_extattr.c8
-rw-r--r--sys/kern/vfs_syscalls.c8
-rw-r--r--sys/sys/jail.h3
4 files changed, 39 insertions, 0 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 79be249..8d19dcb 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -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)
{
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index fac2e2f..5115e1a 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -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);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index fac2e2f..5115e1a 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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);
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 9779363..576d2fd 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -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);
OpenPOWER on IntegriCloud