summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_mib.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2001-12-03 16:12:27 +0000
committerrwatson <rwatson@FreeBSD.org>2001-12-03 16:12:27 +0000
commitb5de44291122e0fc2bf68540749f66b3992d3ea2 (patch)
tree8f9d530e63e21e0286cad851a18efd4acdd6bd28 /sys/kern/kern_mib.c
parentc55fbd48a87bd450592bb317754a6bf3961674ff (diff)
downloadFreeBSD-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.c36
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))
OpenPOWER on IntegriCloud