From f3a8d2f93ce69707ed05a48e89d884046f2d8a6a Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 5 Apr 2007 21:03:05 +0000 Subject: [PATCH] Add security.jail.mount_allowed sysctl, which allows to mount and unmount jail-friendly file systems from within a jail. Precisely it grants PRIV_VFS_MOUNT, PRIV_VFS_UNMOUNT and PRIV_VFS_MOUNT_NONUSER privileges for a jailed super-user. It is turned off by default. A jail-friendly file system is a file system which driver registers itself with VFCF_JAIL flag via VFS_SET(9) API. The lsvfs(1) command can be used to see which file systems are jail-friendly ones. There currently no jail-friendly file systems, ZFS will be the first one. In the future we may consider marking file systems like nullfs as jail-friendly. Reviewed by: rwatson --- lib/libc/gen/getvfsbyname.3 | 7 +++++++ share/man/man9/VFS_SET.9 | 7 +++++++ sys/kern/kern_jail.c | 17 +++++++++++++++++ sys/kern/vfs_mount.c | 7 +++++++ sys/sys/mount.h | 1 + usr.bin/lsvfs/lsvfs.c | 5 +++++ usr.sbin/jail/jail.8 | 10 ++++++++++ 7 files changed, 54 insertions(+) diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3 index 0860c4ec15aa..2c2c97d56d70 100644 --- a/lib/libc/gen/getvfsbyname.3 +++ b/lib/libc/gen/getvfsbyname.3 @@ -81,6 +81,11 @@ data does not represent real files aliases some other mounted FS .It Dv VFCF_UNICODE stores file names as Unicode +.It Dv VFCF_JAIL +can be mounted from within a jail if +.Va security.jail.mount_allowed +sysctl is set to +.Dv 1 . .El .Sh RETURN VALUES .Rv -std getvfsbyname @@ -99,8 +104,10 @@ argument specifies a file system that is unknown or not configured in the kernel. .El .Sh SEE ALSO +.Xr jail 2 , .Xr mount 2 , .Xr sysctl 3 , +.Xr jail 8 , .Xr mount 8 , .Xr sysctl 8 .Sh HISTORY diff --git a/share/man/man9/VFS_SET.9 b/share/man/man9/VFS_SET.9 index 4b55ba75021a..5bc3145ea2ea 100644 --- a/share/man/man9/VFS_SET.9 +++ b/share/man/man9/VFS_SET.9 @@ -70,6 +70,11 @@ Pseudo file system, data does not represent on-disk files. Loopback file system layer. .It Dv VFCF_UNICODE File names are stored as Unicode. +.It Dv VFCF_JAIL +can be mounted from within a jail if +.Va security.jail.mount_allowed +sysctl is set to +.Dv 1 . .El .Sh PSEUDOCODE .Bd -literal @@ -96,6 +101,8 @@ static struct vfsops myfs_vfsops = { VFS_SET(myfs_vfsops, skelfs, 0); .Ed .Sh SEE ALSO +.Xr jail 2 , +.Xr jail 8 , .Xr DECLARE_MODULE 9 , .Xr vfsconf 9 , .Xr vfs_modevent 9 diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 5406ffeb7f26..4170bfec64da 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -72,6 +72,11 @@ SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, &jail_chflags_allowed, 0, "Processes in jail can alter system file flags"); +int jail_mount_allowed = 0; +SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CTLFLAG_RW, + &jail_mount_allowed, 0, + "Processes in jail can mount/unmount jail-friendly file systems"); + /* allprison, lastprid, and prisoncount are protected by allprison_mtx. */ struct prisonlist allprison; struct mtx allprison_mtx; @@ -651,6 +656,18 @@ prison_priv_check(struct ucred *cred, int priv) else return (EPERM); + /* + * Depending on the global setting, allow privilege of + * mounting/unmounting file systems. + */ + case PRIV_VFS_MOUNT: + case PRIV_VFS_UNMOUNT: + case PRIV_VFS_MOUNT_NONUSER: + if (jail_mount_allowed) + return (0); + else + return (EPERM); + /* * Allow jailed root to bind reserved ports. */ diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 08879fd5a193..cb556a219809 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -847,6 +847,8 @@ vfs_domount( vfsp = vfs_byname_kld(fstype, td, &error); if (vfsp == NULL) return (ENODEV); + if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL)) + return (EPERM); } /* * Get vnode to be covered @@ -863,6 +865,11 @@ vfs_domount( return (EINVAL); } mp = vp->v_mount; + vfsp = mp->mnt_vfc; + if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL)) { + vput(vp); + return (EPERM); + } MNT_ILOCK(mp); flag = mp->mnt_flag; /* diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 05400fcc4abd..9009e16880dc 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -427,6 +427,7 @@ struct ovfsconf { #define VFCF_SYNTHETIC 0x00080000 /* data does not represent real files */ #define VFCF_LOOPBACK 0x00100000 /* aliases some other mounted FS */ #define VFCF_UNICODE 0x00200000 /* stores file names as Unicode */ +#define VFCF_JAIL 0x00400000 /* can be mounted from within a jail */ typedef uint32_t fsctlop_t; diff --git a/usr.bin/lsvfs/lsvfs.c b/usr.bin/lsvfs/lsvfs.c index 1e486d7ca462..1f23e1ce5824 100644 --- a/usr.bin/lsvfs/lsvfs.c +++ b/usr.bin/lsvfs/lsvfs.c @@ -105,5 +105,10 @@ fmt_flags(int flags) strcat(buf, "unicode"); } + if(flags & VFCF_JAIL) { + if(comma++) strcat(buf, ", "); + strcat(buf, "jail"); + } + return buf; } diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index 7fd974cab3a5..e9b77e4152dc 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -546,6 +546,15 @@ or clear system file flags; if non-zero, such users are treated as privileged, and may manipulate system file flags subject to the usual constraints on .Va kern.securelevel . +.It Va security.jail.mount_allowed +This MIB entry determines if a privileged user inside a jail will be +able to mount and unmount file system types marked as jail-friendly. +The +.Xr lsvfs 1 +command can be used to find file system types available for mount from within +a jail. +This functionality is disabled by default, but can be enabled by setting this +MIB entry to 1. .El .Pp The read-only sysctl variable @@ -572,6 +581,7 @@ and .Va kern.hostname . .Sh SEE ALSO .Xr killall 1 , +.Xr lsvfs 1 , .Xr newaliases 1 , .Xr pgrep 1 , .Xr pkill 1 ,