diff options
author | rwatson <rwatson@FreeBSD.org> | 2001-12-03 16:12:27 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2001-12-03 16:12:27 +0000 |
commit | b5de44291122e0fc2bf68540749f66b3992d3ea2 (patch) | |
tree | 8f9d530e63e21e0286cad851a18efd4acdd6bd28 /sys/kern/kern_mib.c | |
parent | c55fbd48a87bd450592bb317754a6bf3961674ff (diff) | |
download | FreeBSD-src-b5de44291122e0fc2bf68540749f66b3992d3ea2.zip FreeBSD-src-b5de44291122e0fc2bf68540749f66b3992d3ea2.tar.gz |
o Introduce pr_mtx into struct prison, providing protection for the
mutable contents of struct prison (hostname, securelevel, refcount,
pr_linux, ...)
o Generally introduce mtx_lock()/mtx_unlock() calls throughout kern/
so as to enforce these protections, in particular, in kern_mib.c
protection sysctl access to the hostname and securelevel, as well as
kern_prot.c access to the securelevel for access control purposes.
o Rewrite linux emulator abstractions for accessing per-jail linux
mib entries (osname, osrelease, osversion) so that they don't return
a pointer to the text in the struct linux_prison, rather, a copy
to an array passed into the calls. Likewise, update linprocfs to
use these primitives.
o Update in_pcb.c to always use prison_getip() rather than directly
accessing struct prison.
Reviewed by: jhb
Diffstat (limited to 'sys/kern/kern_mib.c')
-rw-r--r-- | sys/kern/kern_mib.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 37eaf55..dc16a0d 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -48,6 +48,8 @@ #include <sys/systm.h> #include <sys/sysctl.h> #include <sys/proc.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <sys/jail.h> #include <sys/smp.h> @@ -155,14 +157,34 @@ static int sysctl_hostname(SYSCTL_HANDLER_ARGS) { struct prison *pr; + char tmphostname[MAXHOSTNAMELEN]; int error; pr = req->td->td_proc->p_ucred->cr_prison; if (pr != NULL) { if (!jail_set_hostname_allowed && req->newptr) return (EPERM); - error = sysctl_handle_string(oidp, pr->pr_host, + /* + * Process is in jail, so make a local copy of jail + * hostname to get/set so we don't have to hold the jail + * mutex during the sysctl copyin/copyout activities. + */ + mtx_lock(&pr->pr_mtx); + bcopy(pr->pr_host, tmphostname, MAXHOSTNAMELEN); + mtx_unlock(&pr->pr_mtx); + + error = sysctl_handle_string(oidp, tmphostname, sizeof pr->pr_host, req); + + if (req->newptr != NULL && error == 0) { + /* + * Copy the locally set hostname to the jail, if + * appropriate. + */ + mtx_lock(&pr->pr_mtx); + bcopy(tmphostname, pr->pr_host, MAXHOSTNAMELEN); + mtx_unlock(&pr->pr_mtx); + } } else error = sysctl_handle_string(oidp, hostname, sizeof hostname, req); @@ -194,9 +216,11 @@ sysctl_kern_securelvl(SYSCTL_HANDLER_ARGS) * If the process is in jail, return the maximum of the global and * local levels; otherwise, return the global level. */ - if (pr != NULL) + if (pr != NULL) { + mtx_lock(&pr->pr_mtx); level = imax(securelevel, pr->pr_securelevel); - else + mtx_unlock(&pr->pr_mtx); + } else level = securelevel; error = sysctl_handle_int(oidp, &level, 0, req); if (error || !req->newptr) @@ -206,10 +230,14 @@ sysctl_kern_securelvl(SYSCTL_HANDLER_ARGS) * global level, and local level if any. */ if (pr != NULL) { + mtx_lock(&pr->pr_mtx); if (!regression_securelevel_nonmonotonic && - (level < imax(securelevel, pr->pr_securelevel))) + (level < imax(securelevel, pr->pr_securelevel))) { + mtx_unlock(&pr->pr_mtx); return (EPERM); + } pr->pr_securelevel = level; + mtx_unlock(&pr->pr_mtx); } else { if (!regression_securelevel_nonmonotonic && (level < securelevel)) |