diff options
| author | Marko Zec <zec@FreeBSD.org> | 2009-05-08 14:11:06 +0000 |
|---|---|---|
| committer | Marko Zec <zec@FreeBSD.org> | 2009-05-08 14:11:06 +0000 |
| commit | 29b02909eb4d38a8803d0e125285c19c92e34da5 (patch) | |
| tree | 070fe9c96176ed914dfefc12a45fea29b98c4122 /sys/kern | |
| parent | fcec7b25b83cce28458a932d1302235b13cf459e (diff) | |
Notes
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/init_main.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_fork.c | 3 | ||||
| -rw-r--r-- | sys/kern/kern_jail.c | 4 | ||||
| -rw-r--r-- | sys/kern/kern_linker.c | 12 | ||||
| -rw-r--r-- | sys/kern/kern_mib.c | 7 | ||||
| -rw-r--r-- | sys/kern/kern_prot.c | 10 | ||||
| -rw-r--r-- | sys/kern/kern_vimage.c | 23 |
8 files changed, 66 insertions, 3 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 96ebf36cc0d7..97b7f0fcf578 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -454,7 +454,10 @@ proc0_init(void *dummy __unused) p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ #ifdef VIMAGE - p->p_ucred->cr_vnet = LIST_FIRST(&vnet_head); + KASSERT(LIST_FIRST(&vimage_head) != NULL, ("vimage_head empty")); + P_TO_VIMAGE(p) = LIST_FIRST(&vimage_head); /* set ucred->cr_vimage */ + refcount_acquire(&P_TO_VIMAGE(p)->vi_ucredrefc); + LIST_FIRST(&vprocg_head)->nprocs++; #endif #ifdef AUDIT audit_cred_kproc0(p->p_ucred); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a10e915e0a11..89b92c61a1a1 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sdt.h> #include <sys/shm.h> #include <sys/sem.h> +#include <sys/vimage.h> #ifdef KTRACE #include <sys/ktrace.h> #endif @@ -737,6 +738,7 @@ loop: nfound++; PROC_SLOCK(p); if (p->p_state == PRS_ZOMBIE) { + INIT_VPROCG(P_TO_VPROCG(p)); if (rusage) { *rusage = p->p_ru; calcru(p, &rusage->ru_utime, &rusage->ru_stime); @@ -837,6 +839,9 @@ loop: uma_zfree(proc_zone, p); sx_xlock(&allproc_lock); nprocs--; +#ifdef VIMAGE + vprocg->nprocs--; +#endif sx_xunlock(&allproc_lock); return (0); } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 76695e711713..4e8dbb19ee2f 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -350,6 +350,9 @@ norfproc_fail: * are hard-limits as to the number of processes that can run. */ nprocs++; +#ifdef VIMAGE + P_TO_VPROCG(p1)->nprocs++; +#endif /* * Find an unused process ID. We remember a range of unused IDs diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 069f1f0f1b9c..3bc5c10c6765 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2218,6 +2218,10 @@ prison_check(struct ucred *cred1, struct ucred *cred2) if (cred2->cr_prison != cred1->cr_prison) return (ESRCH); } +#ifdef VIMAGE + if (cred2->cr_vimage->v_procg != cred1->cr_vimage->v_procg) + return (ESRCH); +#endif return (0); } diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 2237107e3704..4e0c5a30d3bc 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -992,6 +992,12 @@ kern_kldload(struct thread *td, const char *file, int *fileid) if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0) return (error); +#ifdef VIMAGE + /* Only the default vimage is permitted to kldload modules. */ + if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) + return (EPERM); +#endif + /* * It's possible that kldloaded module will attach a new ifnet, * so vnet context must be set when this ocurs. @@ -1063,6 +1069,12 @@ kern_kldunload(struct thread *td, int fileid, int flags) if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0) return (error); +#ifdef VIMAGE + /* Only the default vimage is permitted to kldunload modules. */ + if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) + return (EPERM); +#endif + CURVNET_SET(TD_TO_VNET(td)); KLD_LOCK(); lf = linker_find_file_by_id(fileid); diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 05f90310ea09..43fcfa4ae0e3 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -208,8 +208,9 @@ static char machine_arch[] = MACHINE_ARCH; SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD, machine_arch, 0, "System architecture"); -/* should become #ifndef VIMAGE */ +#ifdef VIMAGE_GLOBALS char hostname[MAXHOSTNAMELEN]; +#endif /* * This mutex is used to protect the hostname and domainname variables, and @@ -348,12 +349,14 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW, 0, 0, sysctl_kern_config, "", "Kernel configuration file"); #endif -/* should become #ifndef VIMAGE */ +#ifdef VIMAGE_GLOBALS char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */ +#endif static int sysctl_domainname(SYSCTL_HANDLER_ARGS) { + INIT_VPROCG(TD_TO_VPROCG(req->td)); char tmpdomainname[MAXHOSTNAMELEN]; int error; diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 9f13644f1528..b35f81f5316e 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include <sys/socketvar.h> #include <sys/syscallsubr.h> #include <sys/sysctl.h> +#include <sys/vimage.h> #if defined(INET) || defined(INET6) #include <netinet/in.h> @@ -1824,6 +1825,11 @@ crfree(struct ucred *cr) */ if (jailed(cr)) prison_free(cr->cr_prison); +#ifdef VIMAGE + /* XXX TODO: find out why and when cr_vimage can be NULL here! */ + if (cr->cr_vimage != NULL) + refcount_release(&cr->cr_vimage->vi_ucredrefc); +#endif #ifdef AUDIT audit_cred_destroy(cr); #endif @@ -1859,6 +1865,10 @@ crcopy(struct ucred *dest, struct ucred *src) uihold(dest->cr_ruidinfo); if (jailed(dest)) prison_hold(dest->cr_prison); +#ifdef VIMAGE + KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL")); + refcount_acquire(&dest->cr_vimage->vi_ucredrefc); +#endif #ifdef AUDIT audit_cred_copy(src, dest); #endif diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index 21d502e4c3fe..e20b382029f5 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container"); MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); +MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block"); static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; @@ -56,7 +57,13 @@ static int vnet_mod_constructor(struct vnet_modlink *); static int vnet_mod_destructor(struct vnet_modlink *); #ifdef VIMAGE +struct vimage_list_head vimage_head; struct vnet_list_head vnet_head; +struct vprocg_list_head vprocg_head; +#else +#ifndef VIMAGE_GLOBALS +struct vprocg vprocg_0; +#endif #endif void @@ -294,6 +301,8 @@ static void vi_init(void *unused) { #ifdef VIMAGE + struct vimage *vip; + struct vprocg *vprocg; struct vnet *vnet; #endif @@ -301,13 +310,27 @@ vi_init(void *unused) TAILQ_INIT(&vnet_modpending_head); #ifdef VIMAGE + LIST_INIT(&vimage_head); + LIST_INIT(&vprocg_head); LIST_INIT(&vnet_head); + vip = malloc(sizeof(struct vimage), M_VIMAGE, M_NOWAIT | M_ZERO); + if (vip == NULL) + panic("malloc failed for struct vimage"); + LIST_INSERT_HEAD(&vimage_head, vip, vi_le); + + vprocg = malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO); + if (vprocg == NULL) + panic("malloc failed for struct vprocg"); + vip->v_procg = vprocg; + LIST_INSERT_HEAD(&vprocg_head, vprocg, vprocg_le); + vnet = malloc(sizeof(struct vnet), M_VNET, M_NOWAIT | M_ZERO); if (vnet == NULL) panic("vi_alloc: malloc failed"); LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); vnet->vnet_magic_n = VNET_MAGIC_N; + vip->v_net = vnet; /* We MUST clear curvnet in vi_init_done before going SMP. */ curvnet = LIST_FIRST(&vnet_head); |
